常见排序算法总结

排序的概念

1、排序:所谓排序,就是使一串记录,按照其中的某个或某些关键字的大小,递增或递减的排列起来的操作。

2、稳定性:假定在待排序的记录序列中,存在多个具有相同关键字的记录,若经过排序,这些记录的相对次序保持不变,即在原序列中r[i]=r[j],且r[i]在r[j]之前,而在排序后的序列中,r[i]仍在r[j]之前,则称这种排序算法是稳定的;否则称为不稳定的。

3、内部排序:数据元素全部放在内存中的排序。

4、外部排序:数据元素太多不能同时放在内存中,根据排序过程的要求不能在内外存之间移动数据的排序

常见排序如下图

常见排序算法总结_第1张图片

插入排序

基本思想:把待排序的记录按其关键码值的大小逐个插入到一个已经排好序的有序序列中,直到所有的记录插入完为止,得到一个新的有序序列 。

直接插入排序

过程:当插入第i(i>=1)个元素时,前面的array[0],array[1],…,array[i-1]已经排好序,此时用array[i]的排序码与array[i-1],array[i-2],…的排序码顺序进行比较,找到插入位置即将array[i]插入,原来位置上的元素顺序后移。

实例过程

常见排序算法总结_第2张图片

C语言代码

void InsertSort(int *a,int n){
     
	assert(a);
	for(int i=0;i<n-1;i++){
     //控制插入的趟数,因为第一个元素有序,所以趟数是n-1
		int end=i;
		int temp=a[end+1];
		while(end>=0&&a[end]>temp){
     //单趟插入排序,当前元素小于temp时直接插入到当前元素的下一个位置,因为后面所有的元素都往后移动了一个位置
			a[end+1]=a[end];
			end--;
		}
		a[end+1]=temp;
	}
}

直接插入排序特性总结

1、时间复杂度:平均时间复杂度:O(N^ 2),最好情况:O(n),最坏情况:O(n^2)。当元素序列接近有序时,直接插入排序时间效率最高,可以快排的小区间优化。

2、空间复杂度:O(1)。

3、稳定性:稳定

希尔排序(缩小增量排序)

过程:先选定一个整数作为距离,把待排序序列中所有距离相同的分成一个组,并对每一组内的元素进行排序。然后,缩小距离,重复上述分组和排序的工作。当距离>1时为预排序,当距离=1时即是直接插入排序。整个序列即为有序序列。

实例过程

常见排序算法总结_第3张图片

C语言代码

void ShellSort(int *a,int n) {
     
	//	1.gap>1相当于预排序
	//  2.gap=1相当于直接插入排序
	int gap = n;
	while (gap>1) {
     
		gap = gap / 3 + 1;	//+1保证了最后一次一定要为1
		for (int i = 0; i < n - gap;i++) {
     
			int end = i;
			int temp = a[end + gap];
			while (end >= 0) {
     
				if (a[end] > temp) {
     
					a[end+gap] = a[end];
					end -= gap;
				}
				else break;
			}
			a[end + gap] = temp;
		}
	}
}

希尔排序特性总结

1、时间复杂度:平均时间复杂度:O(NlogN),最好情况:O(n^ 1.3),最坏情况:O(n^2)。

2、空间复杂度:O(1)。

3、稳定性:不稳定

4、希尔排序是对直接插入排序的优化

5、gap越大,前面大的数据可以更快的到后面,后面小的数,可以更快的到前面。gap越大,越不接近有序,gap越小,越接近有序。如果gap=1,就是直接插入排序。那么对于接近有序的序列进行直接插入排序算法时间效率是很高效的。所以希尔排序对直接插入排序做了一个很好的优化。


选择排序

基本思想:每一次从待排序的数据元素中选出最大(最小)的一个元素,存放在待排序序列的末尾(起始)位置,直到全部待排序的数据元素排完。

选择排序

过程:
1. 在元素集合array[i]–array[n-1]中选择key最大(最小)的数据元素。
2. 若它不是这组元素中的最后一个(第一个)元素,则将它与这组元素中的最后一个(第一个)元素交换。
3. 在剩余的集合中重复上述过程,直到集合中只剩余一个元素。

实例过程

常见排序算法总结_第4张图片


C语言代码

//升序排序
void SelectSort(int* a, int n) {
     
	assert(a);
	int end = n-1;//控制趟数
	while (end) {
     
		int max = 0;
		for (int i = 0; i <= end; i++) {
     //在剩余数组序列中选择最大元素
			if (a[max] < a[i]) {
     
				max = i;
			}
		}
		swap(a + max, a + end);
		end--;
	}
}

选择排序特性总结

1、时间复杂度:平均时间复杂度:O(n^ 2),最好情况:O(n^ 2),最坏情况:O(n^2)。

2、空间复杂度:O(1)。

3、稳定性:不稳定


堆排序

堆排序详解请参见我另外一篇博客:图解二叉堆:堆排序


交换排序

思想:交换:就是根据序列中两个记录键值的比较结果来对换这两个记录在序列中的位置。

冒泡排序

过程:若是升序排列则是将键值较大的记录向序列的尾部移动,键值较小的记录向序列的前部移动。之所以叫冒泡排序是大的值不断往后移动就像泡一样往后冒。

实例过程

常见排序算法总结_第5张图片


C语言代码

void BubbleSort(int* a, int n) {
     
	assert(a);
	int end = n;//控制趟数
	while (end) {
     
		int exchange=1;
		for (int i = 1; i < end; i++) {
     	//每次将最大冒到剩余数组序列的最后一个位置
			if (a[i] < a[i-1]) {
     
				swap(a + i, a + i - 1);
				exchange=0;
			}
		}
		if(exchange) break;
		end--;
	}
}

冒泡排序特性总结

1、时间复杂度:平均时间复杂度:O(N^ 2),最好情况:O(n),最坏情况:O(n^2)。
2、空间复杂度:O(1)。
3、稳定性:稳定。

快速排序

快速排序详解请参见我另外一篇博客:快速排序(双指针法、挖坑法、前后指针法)递归、非递归实现

归并排序

归并排序详解请参见我另外一篇博客:归并排序(递归实现、非递归实现)、磁盘中的外排序。

你可能感兴趣的:(数据结构,数据结构)