堆的建立、插入、删除以及堆排序

堆的结构为完全二叉树,因此适合用数组来存储,本文建立的是最小堆

代码如下:

/************************************************************************
*
* 文件名:5.1.1.cpp
*
* 文件描述:堆的建立、插入、删除以及堆排序
*
* 创建人:  fdk

* 时  间:  2018-08-11
*
* 版本号:1.0
*
* 修改记录:
*
************************************************************************/
#include <iostream>
#include <cstdlib>
#include <algorithm>
#include <time.h>
using namespace std;
int h[] = {99, 5, 36, 7, 22, 17, 46, 12, 2, 19, 25, 28, 1, 92};  //用来存放堆中元素的数组
int n;          // 堆的大小

/*交换函数用来交换堆中的两个元素的值*/
void Swap (int x, int y)
{
    int temp;
    temp = h[x];
    h[x] = h[y];
    h[y] = temp;
}

/*向下调整函数*/
void SiftDown(int i) //传入一个需要向下调整的结点i,当i为1时即为从堆顶开始向下调整
{
    int t;
    int flag = 0; //flag用来标记是否继续向下调整

    /*当i结点有儿子(其实是至少有左儿子)且需要继续调整的时候循环就执行*/
    while (i * 2 + 1 <= n && flag == 0)
    {
        //首先判断它和左儿子的关系,并用t来记录值较小的结点编号
        if (h[i] > h[i*2+1])
        {
            t = i * 2 + 1;
        }
        else
        {
            t = i;
        }
        /*如果它有右儿子,再对右儿子进行讨论*/
        if (i * 2 + 2 <= n)
        {
            //如果右儿子更小,则更新较小的结点编号
            if (h[t] > h[i*2+2])
            {
                t = i * 2 + 2;
            }
        }
        /*如果发现最小的结点不是自己,说明了子结点中有比父结点更小的*/
        if (t != i)
        {
            Swap(t, i);  //交换t和i
            i = t;       //更新i为刚才的与它交换的儿子结点的编号,便于接下来继续向下调整
        }
        else
        {
            flag = 1;    //否则则说明当前的父结点已经比两个子结点都要小了,不需要再进行调整了
        }
    }
}

/*建立堆函数*/
void Creat()
{
    int i;
    /*从最后一个非叶结点到第一个结点依次进行向下调整*/
    for (i = n / 2; i >= 0; i--)
    {
        SiftDown(i);
    }
}

int DeleteMax()
{
    int t;
    t = h[0];    //用一个临时变量记录堆栈的值
    h[0] = h[n]; //将堆的最后一个点复制到堆顶
    n--;         //堆的元素减少1
    SiftDown(0); //向下调整
    return t;    //返回之前记录的堆的顶点的最小值
}
int main()
{
    n = sizeof(h) / sizeof(h[0]) - 1;
    int num = n;
    cout << n << endl;
    cout << "排序前的序列为:";
    for (int i = 0; i <= num; i++)
    {
        cout << h[i] << " ";
    }
    cout << endl;

    cout << "建堆之后的序列为:";
    Creat();
    for (int i = 0; i <= num; i++)
    {
        cout << h[i] << " ";
    }
    cout << endl;

    cout << "排序后的序列:";
    for (int j = 0; j <= num; j++)
    {
        cout << DeleteMax() << " ";
    }
    cout << endl;
    return 0;
}

猜你喜欢

转载自blog.csdn.net/fdkNeverStopLearning/article/details/81662122