news 2026/6/17 3:55:43

chap 8排序

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
chap 8排序

chap 8排序

动态演示排序网站:Comparison Sorting Visualization

8.1 插入排序

算法思想:

每次将一个待排序的记录插入到前面已经排好序的子序列中,直到所有序列插入完成。

①直接插入排序

代码:
//直接插入排序voidInsertSort(intA[],intn){inti,j,temp;for(i=1;i<n;i++){if(A[i]<A[i-1]){temp=A[i];for(j=i-1;j>=0&&A[j]>temp;j--)A[j+1]=A[j];A[j+1]=temp;}}}

例子

当13待排序时,从后往前依次比较,当 前数 比13大的时候(A[j] > temp),前数后移一个位置( A[j + 1] = A[j] )

当前数不大于13/遍历完 时,循环停止在当前数的后一个位置插入13

注:带哨兵版本
//A[0]空出来用于存当前待存元素voidInsertSort(intA[],intn){inti,j;for(i=2;i<=n;i++){A[0]=A[i];if(A[0]<A[i-1]){for(j=i-1;A[j]>A[0];j--)A[j+1]=A[j];//往后挪一位A[j+1]=A[0];}}}

②折半插入排序

待排序记录前面的序列已经有序,在查找元素的时候采用折半查找的方法。

与折半查找不太相同的是,为了保证排序的稳定性,当找到和待排记录相等的元素时,继续序列右半部分找。

代码:

当low > high时折半查找停止,将[ low , n - 1]中的元素全部右移

voidInsertSort(intA[],intn){inti,j,mid,low,high;for(inti=2;i<=n;i++){A[0]=A[i];if(A[i]<A[i-1]){low=1,high=i-1;while(low<=high){mid=(high+low)/2;if(A[mid]<=A[0])low=mid+1;//等于待排元素的时候向区间的右端查询elsehigh=mid-1;}for(j=i-1;j>low;j--)A[j+1]=A[j];A[high+1]=A[0];}}}

③希尔排序

算法思想:先追求表中元素部分有序,再逐渐逼近全局有序

​ 先将待排序表分割成若干形如 L[ i, i + d, i + 2d, i + 3d, …]这样的特殊子表,对各个子表分别进行插入排序。

再缩小增量d,重复上述过程,直至d = 1.

例子:

​ 当d = 4时,i = 1, i + 4 = 5 为一组,49和76为一组;i= 2, i + 4 = 6为一组,38和13为一组; i = 3, i + 4 = 7为一组,65和27为一组; i = 4,i + 4 = 8,76和49为一组。

​ 当d = 2时,i = 1, 3,5,7为一组; i = 2, 4, 6 , 8为一组

​ 当d = 1时,i = 1, 2, 3, 4, 5, 6, 7, 8为一组

代码:
voidShellSort(intA[],intn){intd,i,j;//d循环步长; i循环各个不同的子序列; j循环子序列里面的元素,间隔步长dfor(d=n/2;d>=1;d/=2){for(i=1+d;i<=n;i++){if(A[i]<A[i-d]){A[0]=A[i];//A[0]不是哨兵,暂存此刻待排元素for(j=i-d;j>0&&A[0]<A[j];j-=d)A[j+d]=A[j];A[j+d]=A[0];}}}}

稳定性:

直接插入排序稳定,希尔排序不稳定。

8.2 交换排序

①冒泡排序

算法思想:

从后往前,两两比较相邻元素,若为逆序则交换他们;当某一趟没有元素交换的时候,说明元素已经有序

代码:
voidBubbleSort(intA[],intn){for(inti=0;i<n-1;i++){booltag=false;for(intj=n-1;j>i;j--){if(A[j-1]>A[j])swap(A[j-1],A[j]);tag=true;}if(tag=false)return;}}intswap(inta,intb){inttemp=a;a=b;b=temp;}

性能:

复杂度:

最好最坏平均
时间复杂度O(n)O(n^2)O(n^2)
比较次数n - 1n(n-1)/2/
交换次数03*n(n - 1)/2/

一次交换需要移动三次元素

稳定性:稳定

适用于:链表和顺序表

②快速排序***

算法思想:

每次选择一个枢轴(一般为首元素),一趟排序划分为左右两个子表,使得左子表中的元素都小于枢轴,右子表中的元素都大于等于枢轴

代码(很重要!!!):
voidQuickSort(intA[],intlow,inthigh){if(low<high){intpivotpos=Partition(A,low,high);QuickSort(A,low,pivotpos-1);QuickSort(A,pivotpos+1,high);}}intPartition(intA[],intlow,inthigh){intpivot=A[low];while(low<high){while(low<high&&A[high]>=pivot)high--;A[low]=A[high];while(low<high&&A[low]<=pivot)low++;A[high]=A[low];}A[low]=pivot;returnlow;}
性能

复杂度:

最坏最优平均
时间复杂度O(n^2)O(n*logn)接近O(n * log n)
空间复杂度O(n)O(logn)O(log n)

稳定性:不稳定

适用于:顺序表

8.3 选择排序

算法思想:每一趟在后面的n - i + 1个待排序列元素中选取关键字最小的元素, 作为有序子序列的第i个元素

①简单选择排序

算法思想:

假设排序表为L[1…n],第i趟排序从L[i…n]中选出关键字最小的元素,并与L(i)交换。

​ 每一趟可以确定一个元素的最终位置

​ 经过n- 1趟,整个序列有序

voidSelectSort(intA[],intn){for(inti=0;i<n;i++){intmin=i;for(intj=i+1;j<n;j++){if(A[j]<A[min])min=j;}if(min!=i)swap(A[i],A[min]);}}
性能:

复杂度:

时间复杂度:O(n^2)

空间复杂度:O(1)

稳定性:不稳定

适用于:链式存储和线性存储的顺序表

②堆排序***

2.1大跟堆建立

算法思想:根大于左右子树,建立的过程让小元素下坠

//建立大根堆voidBuildMaxHeap(intA[],intlen){for(inti=len/2;i>0;i--){HeadAdjust(A,i,len);}}//将以k为根的子树调整为大根堆voidHeadAdjust(intA[],intk,intlen){A[0]=A[k];for(inti=2*k;i<=len;i*=2){if(i<len&&A[i]<A[i+1])i++;if(A[0]>=A[i])break;else{A[k]=A[i];k=i;}}A[k]=A[0];}

例如,将53作为根,调整大根堆。

A[0] = A[k] = 53

i = 2, A[i] < A[i + 1], i =3

53 < 87, A[k] = 87, k = 3

一次for循环调整完

第二次for循环

k = 3, i = 6, 65 < 78, i = 7

A[0] = 53 < 78, A[k] = 78, k = 7

下一次循环,i不满足<len,退出for循环,然后把A[0] = 53放入k的位置。

2.2堆排序

算法思想:每一趟将堆顶元素加入有序子序列(与堆的最后一个元素互换),再将待排序序列再次调整为大根堆

大根堆排序最后得到的是一个递增的序列(每次找出最大的堆顶,但是给他换到最下面去了)

//建立大根堆voidBuildMaxHeap(intA[],intlen){for(inti=len/2;i>0;i--){HeadAdjust(A,i,len);}}//将以k为根的子树调整为大根堆voidHeadAdjust(intA[],intk,intlen){A[0]=A[k];for(inti=2*k;i<=len;i*=2){if(i<len&&A[i]<A[i+1])i++;if(A[0]>=A[i])break;else{A[k]=A[i];k=i;}}A[k]=A[0];}//堆排序的完整逻辑voidHeapSort(intA[],intlen){BuildMaxHeap(A,len){for(inti=len;i>1;i--){swap(A[i],A[1]);HeadAdjust(A,1,i-1);}}}

性能:

时间复杂度:建堆O(n) + 排序O(n*logn) = O(n * logn)

空间复杂度:O(1)

稳定性:不稳定

适用于:线性存储线性表

易考点

(1)下坠一次,若有两个孩子,需要对比两次关键字; 若有一个孩子,需要对比一次

(2)插入:插入元素放到表尾,根据大/小根堆的要求不断上升,直至无法上升 O(log n)

(3)删除:删除元素的位置用表尾元素,然后根据大/小根堆的要求不断下降 O(log n)

(4)大根堆得到的是递增序列; 小根堆得到的是递减序列

8.4 归并排序

核心操作,把数组中的两个有序的组序列合并成一个

int*B=(int*)malloc(n*sizeof(int))//B辅助数组voidMerge(intA[],intlow,intmid,inthigh){inti,j k;for(k=low;k<high;k++)B[k]=A[k];//复制A数组中的元素到Bfor(i=low,j=mid+1,k=i;i<=mid&&j<=high;k++){if(B[i]<=B[j])A[k]=B[i++];elseA[k]=B[j++]}while(i<=mid)A[k++]=B[i++];//剩余的元素while(j<=high)A[k++]=B[j++];}voifMergerSort(intA[],intlow,inthigh){if(low<high){intmid=(high+low)/2;MergerSort(A,low,mid-1);MergerSort(A,mid+1,high);}}
性能

复杂度:时间复杂度:O(n*logn); 空间复杂度:O(n)

稳定性:稳定

适用于:顺序表和链表

8.5 基数排序

不依赖元素之间的比较,而基于关键字各位的大小进行排序

最低位优先法(LSD):按关键字权值递增依次进行排序

关键字有d个分量,各位取值0~r-1

分配O(n) + 收集O®

性能:

时间复杂度O(d(n+r))

空间复杂度O®

稳定的

适用于顺序表和链表

*8.6计数排序

不依赖于比较的算法,对每个待排元素x, C数组先统计各个元素出现的次数, 再遍历一次使得C[i]中存储的是 <= i的元素

然后就可以定位元素的位置。

元素取值[0, k)

voidCountSort(intA[],intB[],intn,intk){inti,C[k];for(i=0;i<n;i++)C[i]=0;for(i=0;i<n;i++)C[A[i]]++;for(i=1;i<n;i++)C[i]+=C[i-1];for(i=n-1;i>=0;i--){//从后往前,确保稳定C[A[i]]--;//本身--B[C[A[i]]=A[i];//C[A[i]]代表次序,A[i]元素本身}}
性能

复杂度:

时间复杂度 O(n + k)

空间复杂度 O(n + k)

稳定的

适用于顺序表

对比

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/6/17 3:42:52

MAA明日方舟自动化助手:游戏效率革命的终极方案

MAA明日方舟自动化助手&#xff1a;游戏效率革命的终极方案 【免费下载链接】MaaAssistantArknights 《明日方舟》小助手&#xff0c;全日常一键长草&#xff01;| A one-click tool for the daily tasks of Arknights, supporting all clients. 项目地址: https://gitcode.c…

作者头像 李华
网站建设 2026/6/17 3:39:21

5分钟快速上手OpenEMS:开源能源管理系统终极指南

5分钟快速上手OpenEMS&#xff1a;开源能源管理系统终极指南 【免费下载链接】openems OpenEMS - Open Source Energy Management System 项目地址: https://gitcode.com/gh_mirrors/op/openems 你是否正在寻找一个能够统一管理太阳能、储能电池和充电桩的智能能源平台&…

作者头像 李华
网站建设 2026/6/17 3:33:50

汽车动力总成ECU参考设计解析:从MPC563xM到SmartMOS的工程实践

1. 项目概述与核心价值 在汽车动力总成的开发领域&#xff0c;尤其是发动机管理系统&#xff08;EMS&#xff09;的设计&#xff0c;工程师们面临的核心挑战是如何在极端严苛的物理环境&#xff08;高温、振动、电磁干扰&#xff09;和功能安全要求下&#xff0c;实现高精度、高…

作者头像 李华
网站建设 2026/6/17 3:31:00

Winhance系统优化大师:专业级Windows性能调优解决方案

Winhance系统优化大师&#xff1a;专业级Windows性能调优解决方案 【免费下载链接】Winhance-zh_CN A Chinese version of Winhance. C# application designed to optimize and customize your Windows experience. 项目地址: https://gitcode.com/gh_mirrors/wi/Winhance-zh…

作者头像 李华