快速排序,堆排序和基数排序

之前我的博客有排序算法总结
十种排序算法 - CSDN博客
https://blog.csdn.net/coolwriter/article/details/78732728

1、快速排序

  快速排序的中心是填坑法,取一个数(这里选取第一个数)作为基准数temp,从队尾开始寻找第一个比基准数小的数a[j],交换a[j]和temp,然后队首开始查找第一个比temp大的数a[i],交换之,遍历的结果是当i>=j时,temp左边的数都小于temp,后边的数都大于temp,这个有点像归并排序。最后利用递归调用完成排序,代码如下:

void QuickSort(int a[], int l,int r){
    if(l<r){
        int i=l,j=r,temp=a[l];
        while(i<j){
            while(i<j&&temp<=a[j])
                --j;
            if(i<j)
                a[i++]=a[j];

            while(i<j&&temp>a[i])
                ++i;
            if(i<j)
                a[j--]=a[i];
        }
        a[i]=temp;
        QuickSort(a,l,i-1);
        QuickSort(a,i+1,r);
    }
}

在笔试题中很多人选择快速排序作为基础算法对数组进行排序,一般认为快速排序是内部排序中最好的排序法之一,其平均时间复杂度为O(nlogn),但在已经完成排序的情况下,其最坏复杂度可以为O(n^2),且不稳定。

2、堆排序

  堆排序是基于完全二叉树的排序方法,其中心思想是首先构造最大堆(或最小堆),即父节点总是大于其子节点,然后将堆化的数组a[0]与a[i]交换,即将最大数置于i位置,再将0—i的继续堆化,重新选出最大的数于a[0],完成第一个排序。经过遍历完成排序,其代码为:

//构造最大堆
void MaxHeapFixDown(int a[], int i, int n){
    int j = 2*i+1;
    int temp = a[i];
    while(j<n){
        if(j+1<n&&a[j]<a[j+1])
            ++j;
        if(temp>a[j])
            break;
        else{
            a[i]=a[j];
            i=j;
            j=2*i+1;
        }
    }
    a[i]=temp;
}

//堆排序
void HeapSort(int a[], int n){
    for(int i= n/2-1;i>=0;i--)
        MaxHeapFixDown(a,i,n);
    for(int i=n-1;i>=1;i--){
        swap(a[i],a[0]);
        MaxHeapFixDown(a,0,i);
    }
}

 堆排序相对快速排序最大的有点时即便在最坏的情况下其复杂度也能达到O(nlogn),但也是不稳定排序.

3、基数排序

  基数排序中心思想是基数排序是按照低位先排序,然后收集;再按照高位排序,然后再收集;依次类推,直到最高位。

//寻找数组中最大数的位数作为基数排序循环次数
int KeySize(int a[], int n){
    int key = 1;
    for(int i=0;i<n;i++){
        int temp = 1;
        int r = 10;
        while(a[i]/r>0){
            temp++;
            r*=10;
        }
        key = (temp>key)?temp:key;
    }
    return key;
}

//基数排序
void RadixSort(int a[], int n){
    int key = KeySize(a,n);
    int bucket[10][10]={0};
    int order[10]={0};
    for(int r = 1;key>0;key--,r*=10){
        for(int i=0;i<n;i++){
             int lsd = (a[i]/r)%10;
             bucket[lsd][order[lsd]++]=a[i];
        }

        int k = 0;
        for(int i = 0;i<10;i++){
            if(order[i]!=0){
                for(int j = 0;j<order[i];j++)
                    a[k++]=bucket[i][j];
            }
            order[i]=0;
        }
    }
}

基数排序是稳定算法,效率很高,其复杂度为O(nlog(r)m),其中r为所采取的基数,而m为堆数。但它只能用在整数的排序中,且需要借助一定的辅助空间。

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值