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

背景:最近在找实习,各家公司面试时关于排序方面被问到最多的就是手写快速排序,其次就是手写堆排序了。关于快速排序,大家可能都比较熟悉,可是堆排序就练习的有点少了其实,我也不例外,也因此丢掉很多很好的实习机会。(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;
}
发布了31 篇原创文章 · 获赞 41 · 访问量 13万+

猜你喜欢

转载自blog.csdn.net/circle2015/article/details/70232404