堆与排序

数据结构与算法之美

28 | 堆和堆排序:为什么说堆排序没有快速排序快?

王争 2018-11-26

 

堆排序是一种原地的,时间复杂度为O(nlogn)的排序算法

 

在美团一面中,问到了堆排序的手写,太久没有看堆排序,所以在这个环节错失良机.

  • 堆是一个完全二叉树
  • 堆中每一个节点的值都必须大与其子树的值
  • 父节点的序号,与左右节点之间存在着关系 .parent *2+1=leftChidren;  parent *2+2=rightChidren;
  • 根节点大于左右两节点为大顶堆,相反,为小顶堆

往堆中插入元素

     往一个堆中添加元素,若直接加入在末尾是不完整的,因此我们需要进行自下向上的调整,这个过程叫做堆化.

#include <iostream>
using namespace std;
//大顶堆
template<typename T>
class heap{
    heap(int n):maxN(n){
        m_heap=new T[maxN];
        if(!m_heap){
            throw ("无法申请内存");
        }
        
    }
    void insert(T &newData){
        if(count>maxN){
           return ;       
        }
        ++count;
        m_heap[count]=newData;
        int i=count;
        while(i/2>0 && m_heap[i]> m_heap[i/2]){
          swap(m_heap[i],m_heap[i-2]);  
          i/=2; 
        }
    }    
    
private:
  T * m_heap;// 存储数组
  int maxN;
  int count=0;
};

 

2 删除堆顶元素,我们需要把堆顶元素和其他元素进行比较,然后把第二大元素进行交换,然后迭代删除

    void pop(){
        if(count<0){
            return ;
        }
        m_heap[0]=m_heap[count];
        heapify(); //调整堆
    }

heapfy 堆化  

heapfy是自顶向下堆化,当删除一个节点,把最右下节点转移过来,进行堆化处理.堆化的过程为log2(n),高度为logn 所以插入和删除的复杂度都是O(logn)

 

堆排序的过程

1 建堆 

   建堆的两种方式,一种就是全部采用插入的方法,第二种就是从底向上进行堆化. 从count/2   ....0 的过程

 

 

    void initHeap(){
        for (int i=count/2;i>=1;--i) {
            heapify(i);
        }
    }

每个节点的堆化为O(logn),所以n个节点为O(nlogn)

 

排序

  这个过程类似与删除堆顶元素,每次删除后,然后下标n的元素放在堆顶,然后在通过堆化的方法,将剩下的n-1元素重新重新建堆,直到排序完成.

 

    void sort(){
        initHeap();
        int i=count;
        while (i>=1) {
          swap(m_heap[i],m_heap[count]);
          --i;
          heapify(i);          
        }
    }

1 堆排序数据访问的方式没有快速排序优化

    堆排序的访问是间隔的,0,1,4.8局部顺序访问,所以CPU缓存是不友好的

2 堆排序的数据交换次数是多于快速排序.

 

 

 

 

 

 

 

 

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值