排序算法个人总结(2)

本文总结了两种常见的排序算法——希尔排序和快速排序。希尔排序是一种改进的插入排序,通过增量序列逐步对元素进行排序。快速排序则是通过选取基准值,将数组分为较小和较大的两部分,然后递归地对这两部分进行排序。文章通过实例演示了这两种排序算法的过程,并讨论了它们的时间复杂度和适用场景。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

/*

*希尔排序

*/

希尔排序属于内部排序中的插入排序,它是不稳定的排序,时间复杂度为O(n2/3)n的2/3次幂,具体的算法步骤不再赘述,看图说话

比如有一串数字为:9,13,8,2,5,13,7,1,15,11  

d1=[10/2]=5     d2=[5/2]=3  d3=[3/2]=1   第一趟五五分,第二趟三三分,第三趟增量必须为1




第一趟排序结果为9,7,1,2,5,13,13,8,15,11


第二趟排序结果:2 5 1 9 7 13 11 8 15 13


第三趟:1 2 5 7 8 9 11 13 13 15


/*

*快速排序

*/

先看一看C程序代码

/*    快  速  排  序    */
#include "stdio.h"

void QuickSort(int e[], int first, int end)
{
	int i=first,j=end,temp=e[first];
	while(i<j)
  {
		while(i<j && e[j]>=temp)
			j--;
		e[i]=e[j];
		while(i<j && e[i]<=temp)
			i++;		
		e[j]=e[i];
  }
	e[i]=temp;
  if(first<i-1)
  	QuickSort(e,first,i-1);
	if(end>i+1)		
		QuickSort(e,i+1,end);
}

void main()
{
	int arr[] = {49, 38, 65, 97, 76, 13, 27, 49};
	int len = 8;
	int i;
	printf("before sort\n");
	for(i=0; i<len; i++)
		printf("%d  ", arr[i]);
	printf("\n");
	
	QuickSort(arr, 0, len-1);
	
	printf("after sorted\n");
	for(i=0; i<len; i++)
		printf("%d  ", arr[i]);
	printf("\n");
}
首先介绍一下思想:

1.设置两个变量I、J,排序开始的时候I:=1,J:=N;
2.以第一个数组元素作为关键数据,赋值给X,即X:=A[1];
3.从J开始向前搜索,即由后开始向前搜索(J:=J-1),找到第一个小于X的值,两者交换;
4.从I开始向后搜索,即由前开始向后搜索(I:=I+1),找到第一个大于X的值,两者交换;
5.重复第3、4步,直到I=J;

实战:比如使用快速排序下列一串数组:49        38       65       97       76       13        27

49        38       65       97       76       13        27

 i                                                                        j

j对应的元素比i对应的元素小,所以交换,j不变,i后移

27        38       65       97       76       13        49

               i                                                          j

i小于j,不能交换,i继续后移

27        38       49       97       76       13        65

                          i                                              j

i大于j,交换,此时此刻j前移,i不变

27        38       49       97       76       13        65

                          i                                  j

j小于i,交换,j不变,i后移

27        38       13       97       76       49        65

                                      i                      j    

i大于j,交换,i不变,j前移

27        38       13       49       76       97        65

                                       i          j

i小于j,i继续后移与j重合,第一趟排序结束,所以排序结果为

27 38 13 49 76 97 65

保证了49前面的元素都比49小,而49后面的元素都比49大

接下来对49前面的元素和后面的元素分别再次进行快速排序,

{13} 27 {38}  49  {65}  76   {97}

快速排序就是利用栈的递归方法,分治思想,栈的最大深度为log2n取值下限+1

在所有同数量级(O(nlogn))的排序方法中,其平均性能最好,若初始记录基本有序,快排将蜕化为冒泡排序,时间复杂度为O(n²),

接下来我要讲一讲我认为最复杂的一种排序——堆排序

/*

*堆排序(Heap Sort)

*/

首先介绍一下小根堆和大根堆

小根堆:每个节点小于等于左、右孩子,且根节点是序列n个元素的最小值

大根堆:每个节点大于等于左、右孩子,且根节点是序列n个元素的最大值

小根堆  




性质:

1.堆是一棵采用顺序存储结构的完全二叉树,k是根节点

2.分为大(小)根堆

3.按元素值非递减排序

4.堆中任一子树也为堆

小根堆排序后得到的是非递减序列

大根堆排序后得到非递增序列

堆排序的时间复杂度为O(N*logN)

下面我们来看看堆的建立、插入元素、删除元素的具体操作

堆的建立:

记住建立过程永远是从上到下,从左到右的顺序,先来热个身

初始化序列表为{3,1,4}


将1 与3进行替换后实现了堆的建立结果:


下面给出以下序列,我将详细讲解如何建立一个小根堆

{49,38,65,97,76,13,27,49}


将此序列看成是一棵完全二叉树,最后一个非终端结点是n/2取值下限个元素,那么筛选就从这个元素开始,如图则从第4个元素97开始筛选,97>49,交换


接下来从第三个元素65开始:13<65,交换


第二个元素为38,不需要调整,第一个元素为49,49<13,交换



再次进行调整得到了小根堆,这就是堆的建立


堆的元素插入:

如果插入2


2与3进行替换得到最终结果为


如果初始插入的是0,将进行两次交换,则最终结果为


堆的元素删除:

如果删除根节点,将以堆中最后一个元素替代之,此时根节点左、右子树均为堆,则仅需自上至下进行调整即可,

堆排序定义:若在输出堆顶的最小值后,使得n-1个元素的序列又建成一个堆,则得到n个元素中的次小值,如此反复执行,便能得到一个有序序列,这个过程称之为堆排序

假如有以下小根堆:


97是最后一个元素,与13进行替换,取出13,




此时27为堆里最小的元素,将27与堆的最后一个元素进行交换,取出27,{13,27}      ,此时97为最后一个元素,代替27


调整后


这种方法叫筛选法,

然后取出38,{13,27,38}    65到根节点进行调整,随后筛选出49,49,65,76,97,这就是堆排序

堆排序适合n较大的文件,深度为k的堆,筛选法关键字比较次数为2(k-1),堆排序在最坏情况下时间复杂度为0(nlogn),相比于快排,这是堆排序最大的优点

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值