数据结构知识整理 - 堆排序

版权声明: https://blog.csdn.net/Ha1f_Awake/article/details/85483733

堆排序(Heap Sort)

(可先回顾“排序算法”)

选择排序的基本思想每一趟从待排序记录中选出关键字最小的记录,按顺序放在已排序的记录序列最后,直到全部记录排序好为止。

堆排序是一种树形选择排序,在排序过程中,将存储待排序记录的顺序表看成是一棵完全二叉树(区别满二叉树)的顺序存储结构。利用完全二叉树中父结点与子结点的内在关系,在当前无序的序列中选择关键字最小(或最大)的记录。

<条件>

1)堆的定义

以任意结点为根结点,根结点的关键字都大于(或小于)左、右子树的根结点。

若堆顶记录的关键字最大,则称堆为大根堆,反之称小根堆

2)完全二叉树的定义

所有序号大于[n/2](n为结点数)的结点都是叶结点。

因此只需要依次将以[n/2]、[n/2-1]、...、[1]的结点作为根结点的子树调整为堆即可。

扫描二维码关注公众号,回复: 5127073 查看本文章

<思路>

(以大根堆为例)

1)调整一个小堆

设根结点为rcds[s],左、右子树根结点分别为rcds[2s]、rcds[2s+1]。

先比较左、右子树根结点的关键字,若较大值为右子树根结点,则右子树根结点与根结点比较。若根结点的关键字更大,则该小堆满足要求;若左、右子树根结点中较大的关键字更大,则交换两个结点。

但是,交换结点后,可能会出现(原)根结点的关键字小于(原)右子树根结点的左、右子树根结点(rcds[2(2s+1)]、rcds[2(2s+1)+1]))的情况,这时候需要继续进行调整,即需要循环或递归。

2)利用完全二叉树的特性,从[n/2]结点开始往前调整小堆

3)经过上面两步只能使一个无序序列刚好构成堆的条件,还未能称为有序序列。但我们可以利用堆的特性,将每次调整完得到的堆顶记录(关键字最大)放到最后(依次由[L.length]、[L.length-1]、...),这样就能得到一个从左往右,关键字从小到大的有序序列。

/*------------调整一个小堆-------------*/

void Adjust_Small_Heap(SqList &L, int s, int m)    /*s为调整根结点,m为序号最大的结点*/
{
    L.rcds[0] = L.rcds[s];        /*暂存根结点的记录*/

    for(int i = 2 * s; i <= m; i *= 2)     /*定位结点的左子树根结点*/
    {
        if((j < m) && (L.rcds[i] < L.rcds[i+1])) i++;    /*如果左小于右,用i表示右*/

        if(L.rcds[0] > L.rcds[i]) break;   /*如果根大于较大的结点,满足堆的条件,跳出循环*/

        L.rcds[s] = L.rcds[i]; s = i;      /*如果没有在上一步跳出循环,交换结点后继续判断是否满足堆的条件*/

    }

    L.rcds[s] = L.rcds[0];    /*经过上面的循环后,s表示的位置可能已经改变,需要重新插入(原)根结点的记录*/

}


/*----------利用完全二叉树的特性------------*/

void UseCBT(SqList &L)            /*CBT->Completed Binary Tree,完全二叉树*/
{
    int m = L.length;

    for(int s = n/2; s >=1; i--)
        Adjust_Small_Heap(L, s, m);
}


/*-------------将大根堆有序化--------------*/

void Heap_Sort(SqList &L)
{
    UseCBT(L);                    /*将无序序列转化成大根堆*/

    for(int i = L.length; i > 1; i--)
    {
        int t = L.rcds[1];        /*将堆顶记录往后存放*/
        L.rcds[1] = L.rcds[i];
        L.rcds[i] = t;

        Adjust_Small_Heap(L, 1, i-1);    /*交换结点后需要调整以rcds[1]为根结点的堆*/
    }
}

猜你喜欢

转载自blog.csdn.net/Ha1f_Awake/article/details/85483733
今日推荐