简单易懂的堆排序,附代码和演示图

堆排序是面试中很重要的一个算法,虽然很多人之前可能有接触过,但或许已经忘了,包括我自己也是,所以今天就来做一下总结,简单易懂

下面先看一下堆排序的动态演示(一个超级好用的网站,各种算法相关的动态图都能演示)
https://www.cs.usfca.edu/~galles/visualization/HeapSort.html
(再附上一个动图,来源leetcode )
在这里插入图片描述

代码实现

#include<bits/stdc++.h>
using namespace std;
//以某个点为父节点构造大根堆
void bigHeapify(int parent, vector<int>& nums, int length)
{
      int child = 2*parent+1;  //父节点的第一个子节点
      while(child<length)
      {
            if (child+1<length && nums[child]<nums[child+1])  //若该父节点有两个子节点,则child指向其中较大的一个
                  child++;
            if (nums[parent] < nums[child]) //若父节点比较大的子节点小,则对他们进行交换
            {
                  swap(nums[parent], nums[child]);
                  parent = child; //这里注意还要继续往下便利,确保下面的堆以然是一个大根堆
                  child = parent*2+1;
            }
            else //父节点比较大字节点大,说明已经是一个大根堆,可以结束
                  return;
      }
}
//以某个点为父节点构造小根堆,原理同上
void smallHeapify(int parent, vector<int>& nums, int length)
{
      int child = 2*parent+1;
      while(child<length)
      {
            if (child+1<length && nums[child+1]<nums[child])
                  child++;
            if (nums[child] < nums[parent])
            {
                  swap(nums[parent], nums[child]);
                  parent = child;
                  child = parent*2+1;
            }
            else
                  return;
      }
}
void initializeHeap(vector<int>& nums, int length)
{
      for (int i=length/2-1; i>=0; i--)
      {
      		//从最后一个非叶子结点开始往上构造大根堆,千万注意起始点和边界条件!
            bigHeapify(i, nums, length); 
      }
}
void display(vector<int>& nums, int length)
{
      cout<<"排序后的数组:";
      for (int i=0; i<length; i++)
            cout<<nums[i]<<" ";
      cout<<endl;
}
void Heap(vector<int>& nums, int length)
{
      for (int i=length-1; i>0; i--) //总共需要交换length-1次
      {
            swap(nums[0], nums[i]);
            display(nums, length);  //将交换一次后的数组先打印出来,方便观察
            bigHeapify(0, nums, i); //交换完之后记得从0这个点构造大根堆
      }
}
int main()
{
      vector<int> nums = {49, 38, 65, 97, 76, 13, 27, 49, 10}; //待排序的数组
      int length = nums.size(); //数组的长度
      initializeHeap(nums, length); //初始化堆,在初始化堆中可以选择构造大根堆或者小根堆
      Heap(nums, length); //调用堆排序算法
      return 0;
}

总结 平均时间复杂度:O(n * log n)
空间复杂度:O(1)
稳定性:不稳定

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值