堆排序以及优先队列

来源:互联网 发布:yum wireshark 编辑:程序博客网 时间:2024/06/05 19:19

算法导论中的堆排序。
主要的几个函数:

三个宏用来表示取父节点和左右子节点,算法导论讲的很详细实现很简单#define PARENT(i)(i/2)#define  LEFT(i)(2*i)#define  RIGHT(i)(2*i+1)class Numbersort{public:    Numbersort()    {        arry=NULL;        nmber=0;    }    ~Numbersort()    {        if (arry!=NULL)        {            delete[]arry;        }    }    int copynumber(int *p,int n);//给arry赋值    void putout();///输出数组    void sortnumber();///顺序排序,检验排序的正确性,堆排序中不用    void max_heapify(int heap_size,int i);//对长度为heap_size的堆的节点进行最大堆排序,以维护当前节点以及子节点的最大堆性质    void build_max_heap();//调用max_heapify构建最大堆    void stack_sort();//对build_max_heap()构建好的最大堆进行排序    void increase_key(int i,int key);//将当前借点i的key增加key(不是增加到key)    void addnum(int newn);//增加newn到最大堆中private:    int *arry;    int nmber;    int size_down;};
函数int copynumber(int *p,int n)、void putout()和sortnumber()没啥好说的。
void Numbersort::max_heapify(int heap_size,int i){    int l=LEFT(i);    int r=RIGHT(i);    int largest=0;    //堆排序的顺序比在数组中的位置大1,所以排序的顺序都要减去1    if (l<=heap_size&&arry[l-1]>arry[i-1])    {        largest=l;    }    else        largest=i;    if (r<=heap_size&&arry[r-1]>arry[largest-1])    {        largest=r;    }    if (largest !=i)    {        int temp=arry[largest-1];        arry[largest-1]=arry[i-1];        arry[i-1]=temp;        max_heapify(heap_size,largest);//递归调用以保证父节点后的子节点是最大堆    }}
void Numbersort::build_max_heap(){    int heap_size=nmber;    int half_size=heap_size/2;//最大堆中的去掉叶节点的节点数    for (int i=half_size;i>0;i--)    {        max_heapify(nmber,i);//对每个父节点逐次调用最大堆    }}
void Numbersort::stack_sort(){    for (int i=size_down;i>1;i--)    {        int temp=arry[0];        int temp2=arry[i-1];        arry[i-1]=arry[0];        arry[0]=temp2;//将最大的arry[0]与还未排序的最后一个交换,则最后一个就排好了数        size_down--;//sizedown减1后,已经排序好的数就不再参与最大堆排序。        max_heapify(size_down,1);        putout();    }}

addnum(int newn)将一个newn元素添加到末尾,然后

void Numbersort::addnum(int newn){    int *p=new int [++nmber];    for (int i=0;i<nmber-1;i++)    {        p[i]=arry[i];    }    if (arry!=NULL)    {        delete arry;        arry=new int[nmber];        for (int i=0;i<nmber-1;i++)        {            arry[i]=p[i];        }        delete p;    }    arry[nmber-1]=0;//将最后一个元素置为0,然后调用increase_key    increase_key(nmber,newn);}

将最大堆的第i个元素增加key

void Numbersort::increase_key(int i,int key){    arry[i-1]+=key;    while(i>1&&arry[PARENT(i)-1]<arry[i-1])    {//如果父节点比子节点小,则交换数,再对父节点进行判断,递归父节点的父节点是否符合。        int temp=arry[PARENT(i)-1];        arry[PARENT(i)-1]=arry[i-1];        arry[i-1]=temp;        i=PARENT(i);    }}

总结:算法很简单,但是实现的时候总是会出现一些小问题,解决的也很爽快,主要还是不够细心,没有在草稿纸上先画一下。
有时候感觉,算法都贴出来有点傻X,这么简单还贴。这是一种小小成就感在内心蒸腾~(-ิo-ิ)

0 0
原创粉丝点击