堆和堆排序与封装

堆是一个完全二叉树说着近似完全的二叉树。
堆主要满足两个性质:
1.父节点一定小于(大于,大根堆)两个子节点的键值。
2.每个子节点都是一个二叉堆。

一般都用数组来表示堆,i结点的父结点下标就为(i – 1) / 2。它的左右子结点下标分别为2 * i + 1和2 * i + 2。如第0个结点左右子结点下标分别为1和2。


101556253070
              (b)储存结构
源码在SVN里面:
http://code.taobao.org/svn/algincpluspluss/trunk
堆实现封装:
#include <iostream>
#include <vector>
#include <math.h>
#include <time.h>
#define LEFT(x) 2*x+1
#define RIGHT(x) 2*x+2
#define PARENT(x) (x-1)/2
using namespace std;
template<class T>
class CHeap{
protected:
    vector<T> m_ar;
    virtual bool g_or_l(T a,T b){
        if(a < b)
            return 1;
        else
            return 0;
    }
    inline void heapswap(int a,int b){
        if (a!=b)//用异或交换的前提条件,要交换的数不能相等,否则都为被置为0
        {
            m_ar[a]=m_ar[a] + m_ar[b];
            m_ar[b]=m_ar[a] - m_ar[b];
            m_ar[a]=m_ar[a] - m_ar[b];
        }
    }
    void heapfix(int i){
        int left = LEFT(i);//左孩子下标
        int right = RIGHT(i);//右孩子下标
        int largest = i;//初始化为节点本身
        if (left<m_ar.size()&&g_or_l(m_ar[i],m_ar[left]))//左孩子存在且大于自己
            largest = left;
        if (right<m_ar.size()&&g_or_l(m_ar[largest],m_ar[right]))//右孩子存在且大于自己
            largest = right;
        if(largest == i)
            return;
        heapswap(largest,i);
        return heapfix(largest);
    }
public:
    T remove(){
        heapswap(0,m_ar.size()-1);
        vector<int>::iterator iter = m_ar.end() - 1;
        T relem = m_ar[0];
        cout<<"relem="<<relem<<endl;
        m_ar.erase(iter);
        heapfix(0);
        return relem;
    }
    void insert(T insert_elem){
        m_ar.push_back(insert_elem);
        int i =m_ar.size() - 1;
        while (PARENT(i) >= 0&&i != 0){
            if(g_or_l(m_ar[PARENT(i)],m_ar[i]))
            {
                heapswap(i,PARENT(i));
                i = PARENT(i);    
            }
            else
                break;
        }
    }
    void heapsort()
    {
        for(int i=(m_ar.size());i>=0;i--)
            heapfix(m_ar,i);
    }
    void traheap()
    {
        int cr=0,linecnt=0;
        for(vector<T>::iterator iter=m_ar.begin();iter!=m_ar.end();iter++)
        {
            cout<<(*iter)<<" ";
            if((++cr)==(int)pow((double)2,(double(linecnt))))
            {
                cout<<endl;    
                cr=0;
                ++linecnt;
            }
        }
    }
    virtual void debug(){
        cout<<"CHeap"<<endl;
    }
};
//小根堆的实现template<class T>
class CHeapsr:public CHeap<T>{
private:
     virtual bool g_or_l(T a,T b){
        if(a < b)
            return 1;
        else
            return 0;
    }
public:
    virtual void debug(){
        cout<<"CHeapsr"<<endl;
    }
};
未封装的实现:
#include <iostream>
#include <vector>
#include <math.h>
#include <time.h>
#define LEFT(x) 2*x+1
#define RIGHT(x) 2*x+2
#define PARENT(x) (x-1)/2
using namespace std;
template<class T>
class CHeap{
private:
    vector<T> ar;
    bool bigroot;
public:
};
inline bool g_or_l(int a,int b){
    if(a < b)
        return 1;
    else
        return 0;
}
inline void heapswap(vector<int>& ar,int a,int b){
    ar[a]=ar[a]^ar[b];
    ar[b]=ar[a]^ar[b];
    ar[a]=ar[a]^ar[b];
}
void heapfix(vector<int>& ar,int i){
        int left = LEFT(i);//左孩子下标
        int right = RIGHT(i);//右孩子下标
        int largest = i;//初始化为节点本身
        if (left<m_ar.size()&&g_or_l(m_ar[i],m_ar[left]))//左孩子存在且大于自己
            largest = left;
        if (right<m_ar.size()&&g_or_l(m_ar[largest],m_ar[right]))//右孩子存在且大于自己
            largest = right;
        if(largest == i)
            return;
        heapswap(largest,i);
        return heapfix(largest);
}
int remove(vector<int>& ar){
    heapswap(ar,0,ar.size()-1);
    vector<int>::iterator iter = ar.end() - 1;
    int relem = (*iter);
    ar.erase(iter);
    heapfix(ar,0);
    return relem;
}
void insert(vector<int>& ar,int insert_elem){
    ar.push_back(insert_elem);
    int i =ar.size() - 1;
    while (PARENT(i) >= 0&&i != 0)
        if(g_or_l(ar[PARENT(i)],ar[i]))
        {
            heapswap(ar,i,PARENT(i));
            i = PARENT(i);    
        }
}
void heapsort(vector<int>& ar)
{
    for(int i=(ar.size());i>=0;i--)
        heapfix(ar,i);
}
int main(int argc, char *args[])
{
    srand(time(NULL));
    vector<int> ar;
    for(int i =0;i<16;i++)
        ar.push_back(rand()%32);
    for(int i =0;i<16;i++)
        cout<<ar[i]<<endl;
    cout<<"==========>"<<endl;
    heapsort(ar);
    int cr =0;
    int linecnt=0;
    for(int i =0;i<16;i++){
        cout<<ar[i]<<" ";
        if((++cr)==(int)pow((double)2,(double(linecnt)))){
            cout<<endl;    cr=0;++linecnt;
        }
    }
    cout<<endl<<"==========heapremove>"<<endl;
    int rem = remove(ar);
    cout<<"removed elem ="<<rem<<endl;
    cr =0;
    linecnt=0;
    for(int i =0;i<ar.size();i++){
        cout<<ar[i]<<" ";
        if((++cr)==(int)pow((double)2,(double(linecnt)))){
            cout<<endl;    cr=0;++linecnt;
        }
    }
    cout<<endl<<"==========heap insert>"<<endl;
    insert(ar,100);
    cr =0;
    linecnt=0;
    for(int i =0;i<ar.size();i++){
        cout<<ar[i]<<" ";
        if((++cr)==(int)pow((double)2,(double(linecnt)))){
            cout<<endl;    cr=0;++linecnt;
        }
    }
    cout<<endl<<"==========>"<<endl;
    return 0;
}


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值