排序算法就是那么回事儿<三>

堆排序:堆每一次DeleteMin的时间复杂度是O(logn),这看起很不错,因为n次出堆也只需要O(nlogn)次。那我们是否可以每次出最小树,这样将数组排序呢?
当然可以!我们这就来实现一下!

如果忘记DeleteMin的实现,我们不妨再重新复习一下。队列那些事儿

int DeleteMin(priority_queue pq){
    if(pq.empty()) error();
    int min=pq.elements[1];
    int lastone=pq.elements[pq.size()--];
    int child;
    for(int i=1;i*2<q.size();i=child){
            child=i*2;
if(child!=pq.size()&&pq.elements[child]>pq.elements[child+1])
        child++;
if(pq.elements[child]<lastone)
    pq.elements[i]=pq.elements[child];              
else 
    break;
    }
    pq.elements[i]=lastone;
    return min;
}

堆排序算法

如果我们每次进行DeleteMin操作,将min存储到一个数组中,这样n次之后就会得到一个排好序的结果。这样的坏处是要求一个O(n)的额外数组,这很明显不如快排。
我们这里有一个小技巧,可以去掉这个额外数组。
每次将最顶端的数字和最末端的数字交换,pq.size()- -,然后就可以利用原本的数组来存储这个结果(虽然是逆序的)
这个算法稍微复杂了一些,这次的数组更“正式”一些(回想一下,deletemin是一个内部结构),下标0处包含着数据。

//i:从i处开始下滤
#define leftchild (i*2+1)
void perdown(int A[],int i,int N){
     int child;
     int tmp;
     for(tmp=A[i];i*2<N-1;i=child){
        child=leftchild(i);
        if(child+1<q.size()&&A[child+1]<A[child])
            child++;
        if(tmp<A[child])
            A[i]=A[child];
        else 
            break;
    }
    A[i]=tmp;
}

也许这段代码比较难以理解,但是现在综合Deletemin就比较简单了,这个过程其实是在给A[i]寻找一个合适的位置

堆排序的正式过程

void HeapSort(int *A,int N){
    for(int i=N/2;i>=0:i--)//BuildHeap
        perdown(A,i,N);
    for(int i=N-1;i>0;i--){
        swap(&A[i],&A[0]);//DeleteMin
        perdown(A,0,N);
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值