排序算法是在我们求职面试的时候有很大的概率会被提及,因为不管是在工程类方向中还是在研究类方向中,排序算法的思想都有广泛的应用。
下面,我就来大致的介绍一下各种面试中常见的排序算法的基本思想和相关的实现,希望对你有所帮助。
以下的排序思想都会基于这个序列21,12,34,67,25,46,52,19
来进行讲解,同时配上适当的图解和代码以及代码注释一起讲解。请放心食用。最后的序列都会按照从小到大的顺序进行排列,大家可以自己修改代码,使得序列按照从大到小的顺序排列,以此来检验自己的学习成果。
大致思想
快速排序也是一种分治算法。对于一个序列,我们把这个序列划分为两个序列,使得第一个序列的所有的值都小于第二个序列的所有的值。然后对于剩下的两个序列,我们继续进行划分,直到最后划分为n个序列,每个序列只有一个元素。那么这个时候这个序列就是从小到大有序的了。
这里我们先来关注如何将序列划分为两个序列,第一个序列的元素都小于第二个序列的元素。这里,我们可以选择一个枢点,然后经过调整,将序列小于这个枢点的元素都放到左边,否则就放到这个枢点的右边。最后,我们当前要处理的序列就形成了三个部分,比枢点小的序列,枢点,比枢点大的序列(注意,这里不要有一个误解,比枢点小的序列组成的元素不一定是内部有序的,也可能是无序的)。如下图:
执行完了上面这步之后,我们就可以确定序列的一个元素的位置了,就是枢点对应的位置。然后我们递归对左右这两个序列执行同样的处理,直到当前序列只有一个元素了。
至此,我们就实现了整个序列按照从小到大进行排序了。大致的过程如下图:
代码思路分析
代码实现
#include<iostream> #define LEN 8 using namespace std; void print(int a[]){ for(int i=0;i<LEN;i++){ cout<<a[i]<<" "; } cout<<endl; } /** * @brief 划分函数,将序列划分为三个部分,小于枢点的序列,枢点,大于枢点的序列 * * @param a 需要划分的数组 * @param left 数组的左端点下标 * @param right 数组的右端点下标 * @return int 枢点的位置 */ int split(int a[],int left,int right){ int i=left,k=left; int temp=a[left]; for(k=left+1;k<=right;k++){ if(a[k]<=temp){ ++i; if(i!=k){ swap(a[i],a[k]); } } } swap(a[i],a[left]); return i; } /** * @brief 快排函数 * * @param a 需要排序的数组 * @param left 数组的区间左端点 * @param right 数组的区间右端点 */ void quickSort(int a[],int left,int right){ if(left<right){ int pos=split(a,left,right); quickSort(a,left,pos-1); quickSort(a,pos+1,right); } } int main(){ int a[8]={21,12,34,67,25,46,52,19}; quickSort(a,0,LEN-1); print(a); return 0; }
复杂度分析
如果这篇帖子对你有用的话,欢迎点赞收藏。你的点赞收藏将是对我最大的鼓励。
春招实习面试经历汇总
面试必问—Redis持久化机制(建议收藏)
互联网话术你知多少?(长期更新中...)
互联网面试算法题题解大合集(强烈建议收藏)
实习经验分享 | 希望可以帮助大家避坑,更早地适应实习生活
牛客回忆录