C++数据结构-堆排序(二叉树堆)

#include <iostream>
#include <iostream>
#define N 12
using namespace std;

/**
*46,74,16,53,14,26,40,53,86,65,27,34从小到大排序
*堆排序
*/
/*************************创建最大堆***************************/
void create_heap(int *nums , int s , int m)
{
    //参数s是最后一个有左右孩子的元素下标
    //参数m是要排序的数字个数
    int temp,j;
    temp=nums[s];
    for(j=2*s;j<=m; j *=2)
    {   //结点有左右孩子 并且 右孩子大于左孩子 的情况下
        if(j<m && nums[j] < nums[j+1] )
              ++j;         //此时右孩子nums[j]是最大的孩子
        //紧接着比较该结点与自己的最大孩子的大小
        if(temp > nums[j]) //结点比最大孩子还大,表明不用换(妙笔,这里的temp不能替换成nums[s])
             break;
        nums[s]=nums[j];   //结点比最大孩子小,所以要和最大孩子互换位置(此时结点及其大孩子的值一样,还未互换完成)
        s=j;               //一旦换了,则换完之后的结点还要跟他的左右孩子进行同上的操作,所以这里是一个循环
    }
    nums[s]=temp;          //(因为在循环中s=j了,所以这个操作相当于把父节点的值换给子节点)
}

/************************堆排序****************************/
void heapSort(int *nums)
{
    //先进行一次整个数列构成最大堆,一共要调整的此时就是有孩子的元素的个数
    //且是从最后一个有孩子的开始调整,直到第一个有孩子的
    for(int i=N/2;i>0;i--)   //确定最后一个有孩子的元素的下标
    {
        //N/2就是这个数列中有孩子的元素的个数
        create_heap(nums,i,N); //N是最后一个元素的下标
    }
    //首尾交换
    for(int i=N;i>1;i--)       //一共换n-1次
    {
        //i个数参与排序,把最后一个与第一个互换
        int temp;
        temp =nums[i];
        nums[i]=nums[1];
        nums[1]=temp;
        //互换之后只剩i-1个参与排序。接着构成堆,再循环,一共循环n-1次
        //此时只有位置1不满足最大堆,所以只需调整第一个元素的位置构成最大堆即可
        create_heap(nums,1,i-1); //记住,这是构成对大堆,参与排序的个数为i-1
    }
}

int main()
{
    //初始化
    int nums[N+1]={0,46,74,16,53,14,26,40,53,86,65,27,34};
    //堆排序
    heapSort(nums);
    //打印结果
    for(int i=1;i<=N;i++)
        cout<<nums[i]<<"  ";
    return 0;
}

猜你喜欢

转载自blog.csdn.net/weixin_43323201/article/details/84828257