IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 数据结构与算法 -> 数据结构(十) —— 排序 -> 正文阅读

[数据结构与算法]数据结构(十) —— 排序

一.排序算法总结

1.各类排序算法总表

?2.排序算法的分类

  • 按数据存储介质:内部排序和外部排序
  • 按比较器个数:? ?串行排序和并行排序
  • 按主要操作:? ? ? ?比较排序和基数排序
  • 按辅助空间:? ?????原地排序和非原地排序
  • 按稳定性:? ? ? ? ? ?稳定排序和非稳定排序
  • 按自然性:???????????自然排序和非自然排序

?3.排序依据原则

  • 插入排序:直接插入排序、折半插入排序、希尔排序
  • 交换排序:简单选择排序、快速排序
  • 选择排序:简单选择排序、堆排序
  • 归并排序:2-路归并排序
  • 基数排序

二.排序算法思想叙述与实现

?1.插入排序

  • 直接插入排序

? ? ? ? 直接插入排序,是一种串行的比较排序算法,常用的思路是在数组a[n] 的第一个元素作为“哨兵”的形式,通过比较大小从而确定位置进行排序。

基本思路:1.将待排序的元素存入到哨兵位置(从第二个位置起);2.通过与非哨兵的其他位置进行顺序比较确定排序位置;3.将此位置放到待排序的位置,将哨兵插入到此位置。结合下图进行理解。

?代码实现:

//直接插入排序
void InsertSort(int num[],int len)
{
	int i, j;
	for (i = 2; i < len; i++)
	{
		if (num[i] < num[i - 1]) {   //若"<",需将num[i]插入有序子表
			num[0] = num[i];         //复制为哨兵
			for (j = i - 1; num[0] < num[j]; --j) {
				num[j + 1] = num[j]; //记录后移
			}
			num[j + 1] = num[0];     //插入到正确的位置
		}
	}
}

总结:

  • 折半插入排序

? ? ? ? 折半插入算法,对直接插入算法的一种改进,将查找正确位置的时候,通过折半查找的方法进行,从而减少查找的时间,提高算法的插入效率。

算法思路:1.将待排序的元素存入到哨兵位置(从第二个位置起);2.通过折半查找的方法进行确定放置的位置;3.将此位置放到待排序的位置,将哨兵插入到此位置。

算法实现:

void BinsertSort(int num[], int len)
{
	int i, j,low,high,mid;
	for (i = 2; i < len; ++i) {   //依次插入第2~第n个位置元素
		num[0] = num[i];          //当前插入元素存入到“哨兵”位置
		low = 1;
		high = i - 1;             //采用二分查找法查找插入位置
		while (low <= high) {
			mid = (low + high) / 2;
			if (num[0] < num[mid])
				high = mid - 1;
			else low = mid + 1;
		}
		for (j = i - 1; j >= high + 1; --j)
			num[j + 1] = num[j];           //移动元素
		num[high + 1] = num[0];            //插入正确位置
	}
}

?总结

  • 希尔排序

? ? ? ? 希尔排序,是一种不稳定的排序算法,通过特定的函数来确定位置,从而插入到序列中。

算法思路:1.将待排序的序列分割成若干子序列;2.分别进行直接插入排序;3.全体记录进行一次全部插入排序。结合下图进行理解。

代码实现

//希尔排序
void ShellSort(int num[], int dlta[], int t,int len)
{
	//按增量序列dlta[0……t-1]对数组num作希尔排序。
	for (int k = 0; k < t; ++k) {
		ShellInsert(num, dlta[k],len); //一趟增量为dlta[k]的插入排序
	}
}
void ShellInsert(int num[], int dk,int len) 
{
	int i,j;
	for (i = dk + 1; i <= len; ++i) {
		if (num[i] < num[i - dk]) {
			num[0] = num[i];
			for (j = i - dk; j > 0 && (num[0] < num[j]); j = j - dk ){
				num[j + dk] = num[j];
			}
			num[j + dk] = num[0];
		}
	}
}

总结:

?

2.交换排序

  • 冒泡排序

? ? ? ? 冒泡排序,最常见的排序算法之一,通过想煮水时冒泡那样子,从下面小到最上面大(反之亦然),通过不断的元素交换位置从而来确定最后的位置,每一趟必有一个元素确定位置。

算法思路:1.确定元素排序顺序;2.通过一个一个比较交换找到最大的放最后,再进行下一轮比较;3.排序n个元素传统算法需要n-1趟遍历交换。下面的代码实现是,添加了一个标志位,如果往后的元素都是顺序了,就不用再进行后面趟次的交换了。

代码实现:

//冒泡排序
void BubbleSort(int num[],int len) {
	int m, j, flag = 1,x; //flag作为是否有交换的标记
	for (m = 1; m <= len - 1 && flag == 1; m++) {
		flag = 0;
		for (j = 1; j <= m; j++) {
			if (num[j] > num[j + 1]) { //发生逆序
				flag = 1;    //发生交换,flag置为1,若本趟没有发生交换,flag保持为0
				x = num[j];
				num[j] = num[j + 1];
				num[j + 1] = x;
			}
		}
	}
}

总结:

  • 快速排序

? ? ? ? 快速排序,快速排序通过选择一个中枢元素,然后数组进行分组,将大的放后,小的放前,然后再对大小两个组再进行同样的操作,运用递归的思想将数组不断地进行分组有序排序。

算法思路:1.任取一个元素(如:第一个)为中心pivot;2.使用两个指针,low?一个指向最前面的元素,high?一个指向最后面的元素,对low值与pivot进行比较,若是小则往后移动,若是大于,则对high值跟pivot进行比较,若是大于则往前移动,若是小于则与low值进行交换,再重复这一操作,直到low = high则停止;3.进行递归分组,直到low = high;

代码实现:

//快速排序
void QSort(int num[], int low, int high) {
	if (low < high) {
		int pivotloc = Partition(num, low, high);
		//将num[low……high]一分为二,pivotloc为枢轴元素排好序的位置
		QSort(num, low, pivotloc - 1); //对低子表递归排序
		QSort(num, pivotloc + 1, high);//对高子表递归排序
	}
}
int Partition(int num[], int low, int high) {
	num[0] = num[low];
	int pivot = num[low];
	while (low < high) {
		while (low < high && num[high] >= pivot) --high;
		num[low] = num[high];
		while (low < high && num[low] <= pivot) ++low;
		num[high] = num[low];
	}
	num[low] = num[0];
	return low;
}

?总结:

3.选择排序

  • 简单选择排序

? ? ? ? 简单选择排序,近似于打擂台的方法,设置一个元素默认为最小或最大,通过将其他元素跟其进行比较,从而选择到比它小的进行交换,有多少元素就进行多少趟的比对选择。

算法思路:1.选定一个元素为擂主;2.对其他元素通过与其进行比较从而选择元素进行交换位置;3.多趟进行交换。

代码实现:

//简单选择排序
void SelectSort(int num[],int len) {
	int i, j,k;
	for (i = 1; i < len; ++i) {
		k = i;
		num[0] = num[i];
		for (j = i + 1; j < len; j++) {
			if (num[j] < num[k]) k = j; //记录最小值位置
		}
		if (k != i) num[i] = num[k]; //交换
	}
}

总结:

  • 堆排序

? ? ? ? 堆排序,是先进行堆建立,然后将元素通过堆的定义插入到堆中,并对堆不断调整后,成为一个大根堆或者小根堆。

算法思路:1.建立堆,将元素放置堆顶,然后再放入第二个元素,若是比它小则接入到孩子结点,若比它大则它成为顶点,顶点成为孩子结点。不断重复从而建立堆。2.堆排序,输出堆顶元素,在将叶子结点放到堆顶,再对堆顶元素跟其底下结点进行比较换位,从而是的每次输出的堆顶元素都为最大的。

代码实现:

//堆排序
void HeapAdjust(int num[], int s, int m)
{
	//已知num[s……m]中记录的关键字除num[s]之外均满足堆的定义,
	//本函数调整num[s]的关键字,使得num[s……m]成为一个大根堆
	int j;
	int rc = num[s];
	for (j = 2 * s; j <= m; j *= 2) {             //沿较大的孩子结点向下筛选
		if (j < m && num[j] < num[j + 1]) ++j;    //j为较大的记录的下标
		if (rc >= num[j]) break;               
		num[s] = num[j];                          //rc应插在位置s上
		s = j;            
	}
	num[s] = rc; //插入
}
void HeapSort(int num[],int n) { //n为数组长度,也为堆的个数
	int i;
	for (i = n / 2; i >= 1; i--)
		HeapAdjust(num, i, n);  //建初始堆
	for (i = n; i > 1; i--) {  //进行n-1趟排序
		Swap(num[1], num[i]);  //交换根与最后一个元素
		HeapAdjust(num, 1, i - 1); //对num[1]到num[i-1]重新建堆
	}
}

?总结:

?

4.归并排序

? ? ? ? ?归并排序是对几个数组进行归并,通过数组中的排序,再进行数组与数组间的排序,从而将数组归并排序成一个数组。用以下图理解即可。代码需要具体问题具体分析。?

5.基数排序

? ? ? ? 基数排序,最主要的思想是进行分配+收集。其算法思想是设置若干个箱子,将关键字为k的记录放入第k个箱子,然后按序号将非空的连接。结合如下图理解即可。

?

?

?三.算法对比和总结

  数据结构与算法 最新文章
【力扣106】 从中序与后续遍历序列构造二叉
leetcode 322 零钱兑换
哈希的应用:海量数据处理
动态规划|最短Hamilton路径
华为机试_HJ41 称砝码【中等】【menset】【
【C与数据结构】——寒假提高每日练习Day1
基础算法——堆排序
2023王道数据结构线性表--单链表课后习题部
LeetCode 之 反转链表的一部分
【题解】lintcode必刷50题<有效的括号序列
上一篇文章      下一篇文章      查看所有文章
加:2022-10-17 12:59:48  更:2022-10-17 13:00:00 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年12日历 -2024/12/28 2:07:48-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码
数据统计