堆排序和快速排序的c++实现

来源:互联网 发布:王者荣耀助手网络错误 编辑:程序博客网 时间:2024/05/29 04:38

背景:最近在找实习,各家公司面试时关于排序方面被问到最多的就是手写快速排序,其次就是手写堆排序了。关于快速排序,大家可能都比较熟悉,可是堆排序就练习的有点少了其实,我也不例外,也因此丢掉很多很好的实习机会。(PS:关于查找那块,问的最多的就是手写二分查找了;树的那块,问的多的就是手写求树的深度、非递归前中后层序遍历二叉树;建议诸位道友,面试前狠很的手写练练这些算法。。。不然后果,你懂得。。捂脸。。)

1、快速排序

特点:是对冒泡排序的改进,属于不稳定的方法。其平均性能是迄今为止所有内排序算法中最好的一种,得到广泛应用,例如UNIX系统的库函数qsort()函数。

时间复杂度: 最好情况O( n*log(n) ) ,最坏情况O( n^2 ),平均情况O( n*log(n) )

空间复杂度:O( n*log(n) )

代码如下:

int Partition(int a[], int first,int end)   //快速排序的一次划分,可用于寻找数组中的第K大数字{    int i=first;//初始化    int j=end;    int tmp;    while(i<j)       //默认比较轴值为第一个元素    {        while(i<j&&a[i]<a[j])         //右侧扫描            j--;        if(i<j)                       //将较小的记录移到前面        {            tmp=a[i];            a[i]=a[j];            a[j]=tmp;            i++;        }        while(i<j&&a[i]<a[j])        //左侧扫描            i++;        if(i<j)                      //将较大的记录移到前面        {            tmp=a[i];            a[i]=a[j];            a[j]=tmp;            j--;        }    }    return i;                    //i为轴值记录的最终位置}void QuickSort(int a[],int first,int end){    int pivot;     if(first<end)                  //区间长度大于1,执行一次划分,否则递归结束    {        pivot=Partition(a,first,end);   //一次划分        QuickSort(a,first,pivot-1);     //递归对左侧子序列进行快速排序        QuickSort(a,pivot+1,end);      //递归对右侧子序列进行快速排序    }}

2、堆排序

特点:它的思想是利用的堆这种数据结构,堆可以看成一个完全二叉树,所以在排序中比较的次数可以做到很少。不稳定排序,原地排序。

时间复杂度: 最好情况O( n*log(n) ) ,最坏情况O( n*log(n) ),平均情况O( n*log(n) )

空间复杂度:O( 1 )

代码如下:

void HeadAdjust(int a[],int k,int m)//建立最大堆{    int i=k;               //i指向被筛选节点    int j=2*i+1;           //j指向其左孩子,因为数组下标从0开始,故+1    int tmp;    while(j<=m)                    //筛选还没进行到的叶子节点    {        if(j<m&&a[j]<a[j+1])       //比较i的左右孩子,j指向较大者            j++;        if(a[i]>a[j])             //根节点已经大于左右孩子的最大者            break;        else        {            tmp=a[i];               //否则交换            a[i]=a[j];            a[j]=tmp;            i=j;                     //对变换后的较大孩子进行调整            j=2*i+1;        }    }}void HeapSort(int a[], int n)//堆排序中的调整堆{    int tmp;    for(int i=n/2-1;i>=0;i--)   //初始化堆,从最后一个非叶子节点开始,数组下标从0开始,故-1        HeadAdjust(a,i,n-1);    for(int j=n-1;j>0;j--)      //重复执行移走堆顶,然后重建堆    {        tmp=a[0];        a[0]=a[j];        a[j]=tmp;        HeadAdjust(a,0,j-1);    }}

对以上快速排序和堆排序的测试代码:

int main(){    int a[8]={36,30,18,40,32,45,22,50};    for(int j=0;j<8;j++)        cout<<a[j]<<" ";    cout<<endl;    HeapSort(a,8);//两者任意测试一个    QuickSort(a,0,7);//两者任意测试一个    for(int i=0;i<8;i++)        cout<<a[i]<<" ";    cout<<endl;       return 0;}
0 0
原创粉丝点击