数据结构—希尔、快速、堆、归并排序

本文介绍了四种经典的排序算法:希尔排序、快速排序、堆排序和归并排序。希尔排序是插入排序的改进版,通过增量逐步减少的方式提高效率;快速排序基于分治策略,每次选取基准元素进行划分;堆排序利用堆的性质进行排序,分为建堆和调整堆的过程;归并排序则通过合并两个有序序列得到新的有序序列,保证排序稳定性。这四种算法的时间复杂度均为O(n*logn),但前三种排序结果不稳定,而归并排序稳定。
摘要由CSDN通过智能技术生成

1.希尔排序

  • 希尔排序是希尔(Donald Shell)于1959年提出的一种排序算法。希尔排序也是一种插入排序,它是简单插入排序经过改进之后的一个更高效的版本,也称为缩小增量排序同时该算法是冲破O(n2)的第一批算法之一。它与插入排序的不同之处在于,它会优先比较距离较远的元素。希尔排序又叫缩小增量排序。

1.1 基本思想

  • 将待排序列划分为若干组,在每一组内进行插入排序,以使整个序列基本有序,然后再对整个序列进行插入排序。
  • 例如:将 n 个数据元素分成 d 个子序列:
  • { R[1],R[1+d],R[1+2d],…,R[1+kd] }
  • { R[2],R[2+d],R[2+2d],…,R[2+kd] }
  • { R[d],R[2d],R[3d],…,R[kd],R[(k+1)d] }
  • 其中,d 称为增量,它的值在排序过程中从大到小逐渐缩小,直至最后一趟排序减为 1。

1.2 图示

 1.3 代码实现

// 分类 -------------- 内部比较排序
// 数据结构 ---------- 数组
// 最差时间复杂度 ---- O(n^2)
// 最优时间复杂度 ---- O(n^1.3)
// 平均时间复杂度 ---- O(nlogn)
// 所需辅助空间 ------ O(1)
// 稳定性 ------------ 不稳定

#include <stdio.h>
#include <stdlib.h>

void println(int array[], int len)
{
	int i = 0;

	for (i = 0; i < len; i++)
	{
		printf("%d ", array[i]);
	}

	printf("\n");
}

void ShellSort(int array[], int len)
{
	int i = 0;
	int j = 0;
	int k = -1;
	int temp = -1;
	int gap = len;

	do
	{
		gap = gap / 3 + 1; // gap如何变化无强制要求,但gap最终要收敛于1,工程实践经验除以3性能较好,现无理论方法证明。
		//gap = 1;   // gap=1时,希尔排序退化为擦入排序

		// 分组
		for (i = gap; i < len; i += gap)   
		{
			k = i;
			temp = array[k];

			// 擦入排序
			for (j = i - gap; (j >= 0) && (array[j] > temp); j -= gap)
			{
				array[j + gap] = array[j];
				k = j;
			}

			array[k] = temp;
		}
	} while (gap > 1);
}

int main(int argc, char *argv[])
{
	int array[] = { 21,25,49,25,16,8 };
	int len = sizeof(array) / sizeof(*array);

	printf("希尔排序前:");
	println(array, len);

	ShellSort(array, len);

	printf("希尔排序前:");
	println(array, len);

	system("pause");

	return 0;
}
  •  运行结果:
  • 希尔排序是不稳定的排序算法虽然一次插入排序是稳定的,不会改变相同元素的相对顺序,但在不同的插入排序过程中,相同的元素可能在各自的插入排序中移动,最后其稳定性就会被打乱。
  • 比如序列:{ 3, 5, 10, 8, 7, 2, 8, 1, 20, 6 },h=2时分成两个子序列 { 3, 10, 7, 8, 20 } 和  { 5, 8, 2, 1, 6 } ,未排序之前第二个子序列中的8在前面,现在对两个子序列进行插入排序,得到 { 3, 7, 8, 10, 20 } 和 { 1, 2, 5, 6, 8 } ,即 { 3, 1, 7, 2, 8, 5, 10, 6, 20, 8 } ,两个8的相对次序发生了改变。

2.快速排序

2.1 基本思想

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值