news 2026/3/26 19:42:59

归并排序与快速排序

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
归并排序与快速排序

归并排序

介绍

有时候我们需要把两个有序的序列进行合并从而得到有序的大序列,基于这个思想,便引出了归并排序,其思路就是把一个无序序列拆分成多个有序序列(当序列的元素为1时就是有序序列),然后对所有序列进行合并操作,最终得到一整个有序序列。

实现

typedef int ElementType; void Merge(ElementType A[],ElementType TmpArray[],int Lpos,int Rpos,int RightEnd) { int i,LeftEnd,NumElements,TmpPos; LeftEnd=Rpos-1; TmpPos=Lpos; NumElements=RightEnd-Lpos+1; while (Lpos<=LeftEnd && Rpos<=RightEnd) { if (A[Lpos]<=A[Rpos]) { TmpArray[TmpPos++]=A[Lpos++]; }else { TmpArray[TmpPos++]=A[Rpos++]; } } while (Lpos<=LeftEnd) { TmpArray[TmpPos++]=A[Lpos++]; } while (Rpos<=RightEnd) { TmpArray[TmpPos++]=A[Rpos++]; } for (i=0;i<NumElements;i++,RightEnd--) { A[RightEnd]=TmpArray[RightEnd]; } } void Msort(ElementType A[],ElementType TmpArray[],int Left,int Right) { int Center; if (Left<Right) { Center=(Left+Right)/2; Msort(A,TmpArray,Left,Center); Msort(A,TmpArray,Center+1,Right); Merge(A,TmpArray,Left,Center+1,Right); } } void MergeSort(ElementType A[],int N) { ElementType *TmpArray; TmpArray = (ElementType*)malloc(N*sizeof(ElementType)); if (TmpArray!=NULL) { Msort(A,TmpArray,0,N-1); free(TmpArray); }else { printf("Not enough memory for Merge Sort\n"); } }

算法有两个重要的操作,一个是将大序列分成小序列的操作,一个是将两个有序序列合并成有序大序列的操作。

合并操作的逻辑:假设要合并序列A和序列B(都是升序),首先创建一个空间大小为A和B元素数量之和的大小。然后比较A和B最左边的元素,较小的放新序列里,较大的那个和另一个序列的下一个元素比,持续这个过程直到其中一个序列遍历完,那就把另一个序列剩下的元素放到新序列里就可以了。

递归拆分的逻辑:将数组从中间拆成左右两部分,再对左右两部分再以中间拆成两部分,一直这样拆到小序列只要一个元素,然后再对这两个小序列进行合并操作,一步一步合并直至左右两大部分的序列进行最后一次合并成为最终完成排序的总序列。

这里开了一个临时变量TmpArray为了方便后面进行合并操作时频繁新辟用于存两个序列的新数组。

分析

归并操作包括拆分和合并,将数组拆分成许多小数组的的过程一共要进行LogN次,每一层的合并最坏要比较N次,所以总的时间复杂度为O(LogN)。

归并排序是稳定排序,因为每一次的拆分都是相邻序列的拆分,合并时若两元素相等,也是先将左数组的元素放入临时数组,这不改变相同元素的相对位置。

快速排序

介绍

当得到一个无序数组,那我们随机选其中一个元素,然后让剩下的元素中小于它的排在它左边,大于它的元素排在它右边,这样我们就让这个元素归位了,它所在的位置不会在变了。接着再对剩下的元素重复进行这样的操作,这样随着一个个元素的归位,序也就排好了。

实现

typedef int ElementType; #define Cutoff (3) void Swap(ElementType *a,ElementType *b) { ElementType Tmp=*a; *a=*b; *b=Tmp; } void InsertionSort(ElementType A[],int N) { int j,P; ElementType Tmp; for (P=1;P<N;P++) { Tmp=A[P]; for (j=P;j>0&&A[j-1]>Tmp;j--) { A[j]=A[j-1]; } A[j]=Tmp; } } ElementType Median3(ElementType A[],int Left,int Right) { int Center = (Left+Right)/2; if (A[Left]>A[Center]) { Swap(&A[Left],&A[Center]); } if (A[Left]>A[Right]) { Swap(&A[Left],&A[Right]); } if (A[Center]>A[Right]) { Swap(&A[Center],&A[Right]); } Swap(&A[Center],&A[Right-1]); return A[Right-1]; } void Qsort(ElementType A[],int Left,int Right) { int i,j; ElementType Pivot; if (Left+Cutoff<=Right) { Pivot=Median3(A,Left,Right); i=Left; j=Right-1; for (;;) { while (A[++i]<Pivot) {} while (A[--j]>Pivot) {} if (i<j) { Swap(&A[i],&A[j]); }else { break; } } Swap(&A[i],&A[Right-1]); Qsort(A,Left,i-1); Qsort(A,i+1,Right); }else { InsertionSort(A+Left,Right-Left+1); } } void QuickSort(ElementType A[],int N) { Qsort(A,0,N-1); }

这里的排序操作比较灵活,算法步骤如下:

为了提高算法效率防止出现快速排序最坏的情况(避免选到极值做枢轴),先找到待排序数组的左端点,中点和右端点这三个位置,然后对这三个位置进行排序,排好序后将中点的元素和Right-1处的元素进行交换并且将其作为枢轴(枢轴的左边所有元素小于枢轴本身,枢轴的右边所有元素大于枢轴本身)。

快速排序的核心操作(此操作没有新辟一块空间来存储经交换后快速排序的数组,所以空间复杂度较低):使用双指针i,j分别从数组最左端和Right-2两次开始遍历,先i右移直到找比枢轴大的元素后,再j左移直到找到比枢轴小的元素,这样如果顺利的话会出现i位置的元素小于j位置的元素,那就交换这两个元素,然后i,j指针接着移动重复上面的操作,若出现i的元素大于等于j位置的元素,说明i,j指针已经不在正确的左右区间了,即此时i的位置的元素是第一个大于枢轴的元素的位置,那就将枢轴和i位置进行交换,这样枢轴的左侧全是小于它的元素,枢轴右侧都是大于它的元素。

接着再对枢轴左侧的子数组(left到i-1)和右侧数组(i+1到Right)递归地进行快速排序的核心操作,直到某个小数组的长度小于3,数组长度太小用快速排序还是太烦琐了,使用就对数组长度小于3的小序列进行插入排序。这样就逐步完成了整个序列的排序

分析

和归并排序一样,选数组的操作及递归层数为LogN,每一层最坏要遍历N个元素,所以快速排序的时间复杂度是O(NLogN)。

快速排序是不稳定排序,双指交换元素时可能会打乱相同元素的相对位置。

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

低成本高性能AI推理:GPT-OSS-20B在消费级设备上的表现

低成本高性能AI推理&#xff1a;GPT-OSS-20B在消费级设备上的表现 你有没有想过&#xff0c;一台普通的笔记本电脑也能跑得动一个接近GPT-4水平的语言模型&#xff1f;不是通过云端API调用&#xff0c;而是完全本地、离线运行&#xff0c;不上传任何数据&#xff0c;也不花一分…

作者头像 李华
网站建设 2026/3/21 3:10:59

如何在Dify智能体平台部署gpt-oss-20b实现私有化AI服务

如何在 Dify 智能体平台部署 gpt-oss-20b 实现私有化 AI 服务 当企业开始认真对待 AI 的落地——不是停留在演示 PPT 上&#xff0c;而是真正嵌入业务流程时&#xff0c;一个绕不开的问题就浮现了&#xff1a;我们能不能自己掌控模型&#xff1f; 公有云大模型 API 确实方便&am…

作者头像 李华
网站建设 2026/3/25 13:20:07

Wan2.2-T2V-A14B为何能在物理模拟和动态细节上表现卓越?

Wan2.2-T2V-A14B为何能在物理模拟和动态细节上表现卓越&#xff1f; 在AI生成内容的浪潮中&#xff0c;视频生成正从“能出画面”迈向“像真实世界一样动起来”的新阶段。过去几年里&#xff0c;文本到视频&#xff08;Text-to-Video, T2V&#xff09;模型虽然实现了从一句话生…

作者头像 李华
网站建设 2026/3/24 0:26:16

智慧树视频学习效率革命:3步实现自动化学习流程

智慧树视频学习效率革命&#xff1a;3步实现自动化学习流程 【免费下载链接】zhihuishu 智慧树刷课插件&#xff0c;自动播放下一集、1.5倍速度、无声 项目地址: https://gitcode.com/gh_mirrors/zh/zhihuishu 还在被智慧树网课的繁琐操作困扰吗&#xff1f;每个视频都需…

作者头像 李华
网站建设 2026/3/24 10:29:24

3分钟搞定网页视频下载:VideoDownloadHelper终极使用指南

3分钟搞定网页视频下载&#xff1a;VideoDownloadHelper终极使用指南 【免费下载链接】VideoDownloadHelper Chrome Extension to Help Download Video for Some Video Sites. 项目地址: https://gitcode.com/gh_mirrors/vi/VideoDownloadHelper 还在为无法保存网页视频…

作者头像 李华
网站建设 2026/3/26 12:18:01

2025年AI工具市场品牌拆解报告|附28页PDF文件下载

本文提供完整版报告下载&#xff0c;请查看文后提示。以下为报告节选&#xff1a;......文│解数咨询、D17数据库本报告共计&#xff1a;28页。如欲获取完整版PDF文件。最后我在一线科技企业深耕十二载&#xff0c;见证过太多因技术卡位而跃迁的案例。那些率先拥抱 AI 的同事&a…

作者头像 李华