当前位置:   article > 正文

经典排序算法----堆排序(C语言实现)_大根堆排序算法c

大根堆排序算法c

算法表述:

堆排序的基本原理为将待排序序列构造成一个大根堆,此时,整个序列的最大值就是堆顶的根节点。将其与末尾元素进行交换,此时末尾就为最大值。然后将剩余n-1个元素重新构造成一个大根堆,重复上述操作,最终序列为有序。

备注:大根堆是每个结点的值都大于或等于其左右孩子结点的值;小根堆是每个结点的值都小于或等于其左右孩子结点的值。

如图所示:

而实际上堆的存储形式是一维数组

算法执行过程分析:

例如:25、15、88、45、8、1、33、21、55、6
如图所示:

具体步骤:
说明:最开始 i 为最后一个结点的位置,依据树的性质,推算该结点的双亲结点,我们将之标记为 s。接下来比较双亲结点和叶子结点,并进行交换,然后找到下一个双亲结点,重复上述操作,直到最后达到根节点,比较交换完成后,此时大根堆或小根堆便建立完成。(下面我们按照从小到大进行排序,因此我们建立大根堆)
(1)第一次排序:

(2)第二次排序:

以此类推,可得最后一次排序情况为:

此时排为大根堆,接下来只需要将根节点和最后一个节点交换值,然后对根节点进行一次排序即可.
如图所示:此时排为大根堆,接下来只需要将根节点和最后一个节点交换值,然后对根节点进行一次排序即可.
如图所示:

代码实现:

  1. void Adjust (int *arr,int start,int end)
  2. {
  3. int temp = arr[start];
  4. for(int i = 2*start +1;i<= end;i = 2*i+1) //i是左孩子下标
  5. {
  6. //判断是否有右孩子
  7. if(i < end && arr[i] < arr[i+1]) //说明有右孩子,左孩子小于右孩子
  8. {
  9. i++;
  10. }
  11. if(arr[i] > temp)
  12. {
  13. arr[start] = arr[i];
  14. start = i;
  15. }
  16. else
  17. {
  18. break;
  19. }
  20. }
  21. arr[start] = temp;
  22. }
  23. void Heap_Sort(int *arr,int len)
  24. {
  25. int i = 0;
  26. for(i = (len-1-1)/2;i >= 0;i--)
  27. {
  28. Adjust(arr,i,len-1);
  29. }
  30. //此时已经是大根堆
  31. for(i = 0;i < len-1;i++)
  32. {
  33. int temp = arr[0];
  34. arr[0] = arr[len-1-i];
  35. arr[len-1-i] = temp;
  36. Adjust(arr,0,len-1-i-1);
  37. }
  38. }

备注:
父====>>子
若父为n,则其右孩子为2n+1;左孩子为2n+2。
子====>>父
若子为n,则其父为(n-1)/2;

总结:

  • 时间复杂度:O(nlog2n)
  • 空间复杂度:O(log2n)
  • 稳定性:不稳定排序
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/菜鸟追梦旅行/article/detail/697399
推荐阅读
相关标签
  

闽ICP备14008679号