堆排序算法得实现

堆排序算法得核心思想是:
1 将待排序序列构造成堆得形式
2 每次将堆顶和末尾空间交换值,然后再重新调整被破坏得堆结构。

大致实现步骤:
1 先从最后的非叶子节点开始构建最小得堆,然后再从下向上构建整个堆结构
2 交换并调整堆结构
代码实现如下:

void Swap(int* param1, int* param2)
{
  int tmpValue = *param1;
  *param1 = *param2;
  *param2 = tmpValue;
}

//将子树构造成堆
void ChildTreeToHeap(int* array, int rootIndex, int endIndex)
{
  int dadIndex = rootIndex;
  int SonIndex = dadIndex * 2 + 1;  

  //从根节点从上到下得构建堆,该情况只会比较直接父节点和子节点得大小关系,
  //不会比较孙子节点和父节点得大小关系。
  //所以如果以此方式构建堆,前提得保证原先得子树就是堆结构。
  //此处就能看出 为什么在堆排序前 先从length /2 -1为根节点得地方构建一个堆得原因了。

  while (SonIndex <= endIndex)
  {
    if (SonIndex + 1 <= endIndex && array[SonIndex] < array[SonIndex + 1])
      SonIndex++;

    if (array[dadIndex] < array[SonIndex])
    {
      Swap(&array[dadIndex], &array[SonIndex]);
      dadIndex = SonIndex;
      SonIndex = dadIndex * 2 + 1;
    }
    else
    {
      return;
    }
  }
}

void HeapSoft(int* array, int length)
{
  //1 先从 最后的非叶子节点开始 建立一个最大堆,
  for (int i = length / 2 - 1; i >= 0; i--)
  {
    //此处的i 是子树的根节点,length / 2 - 1 是最后的那个子树的根节点下标
    ChildTreeToHeap(array, i, length - 1);
  }
  //此时已经构造了一个堆
  for (int i = length - 1; i > 0; i--)
  {
    Swap(&array[0], &array[i]);
    //此处堆结构被破坏,所以得重新在原来得基础上构建。
    ChildTreeToHeap(array, 0, i - 1);
  }
}

堆排序算法分析:
1 在构建整个堆得过程中,将待排序得序列转换成完全二叉树的形式。
2 比较过程先从左右得最小子树开始,有效得避免了更多的构造堆过程中得回溯比较过程。
3 将整个序列分成了左右子树两部分,并分开比较,避免了许多无谓得比较。
4 每次交换得过程中 ,只破环了树中一部分子树得堆结构,再次调整堆的时候就避免了,不必要的比较。

注:
谨记每一次元素的交换都有可能造成,堆结构的破坏所以在每一次产生了交换,就得重新调整成堆结构。 这样才能形成以后的比较次数更少。

堆排序不是稳定的排序。
堆排序的时间复杂度:O (nlgn)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值