【算法】堆排序算法Heap Sort

叁歲伎倆 2022-10-31 00:50 233阅读 0赞

视频学习:https://www.bilibili.com/video/BV1Eb41147dK

堆排序基础

(1)满足完全二叉树
(2)父节点的值大于子节点的值(视频讲的是大顶堆)

完全二叉树

在这里插入图片描述
这七个都是完全二叉树

完全二叉树:一个父节点只能有两个子节点,并且必须从上到下,从左到右这样生成节点。

这样就不是完全二叉树(这里构造完全二叉树要从最左边开始添加)
在这里插入图片描述
这样就是个完全二叉树
在这里插入图片描述
大顶堆完全二叉树:父节点一定要大宇子节点,如下
在这里插入图片描述

建堆

在这里插入图片描述

在这里插入图片描述

代码一:建堆

在这里插入图片描述

  1. #include <bits/stdc++.h>
  2. using namespace std;
  3. void swap(int arr[],int i,int j)//交换函数
  4. {
  5. int temp=arr[i];
  6. arr[i]=arr[j];
  7. arr[j]=temp;
  8. }
  9. void heapify(int tree[],int n,int i)//建堆
  10. {
  11. //n是有多少个节点,i是对哪个节点做heapify操作
  12. if(i>=n)
  13. {
  14. return 0;
  15. }
  16. int c1=2*i+1;
  17. int c2=2*i+2;
  18. int max=i;
  19. //在三个值中要找出最大值
  20. if(c1<n&&tree[c1]>tree[max])
  21. {
  22. max=c1;
  23. }
  24. //c1小于n是为了防止越界
  25. if(c2<n&&tree[c2]>tree[max])
  26. {
  27. max=c2;
  28. }
  29. if(max!=i)
  30. {
  31. swap(tree,max,i);//如果max不等于i,那么交换max和i,此时tree[max]
  32. heapify(tree,n,max);//递归,对下一个子节点(即下一个堆的父节点)继续做heapify
  33. }
  34. }
  35. int main()
  36. {
  37. int tree[]={
  38. 4,10,3,5,1,2}
  39. int n=6;
  40. heapify(tree,n,0);
  41. int i;
  42. for(i=0;i<n;i++)
  43. {
  44. cout<<tree[i]<<endl;
  45. }
  46. return 0;
  47. }

这个代码之后建成的堆
在这里插入图片描述

代码二:建堆

在这里插入图片描述
从倒数第二层开始做heapify,一个个节点往上排序

  1. void build_heap(int tree[],)
  2. {
  3. int last_node=n-1;//要开始heapify的最后一个节点
  4. int parent=(last_node-1)/2;
  5. int i;
  6. for(i=parent;i>=0;i--)
  7. {
  8. heapify(tree,n,i);
  9. }
  10. }

建堆之后做堆排序

此时已经可以保证每个父节点都大于子节点
在这里插入图片描述

完整版代码

  1. #include <bits/stdc++.h>
  2. using namespace std;
  3. void swap(int arr[],int i,int j)//交换函数
  4. {
  5. int temp=arr[i];
  6. arr[i]=arr[j];
  7. arr[j]=temp;
  8. }
  9. void heapify(int tree[],int n,int i)//建堆
  10. {
  11. if(i>=n)
  12. {
  13. return ;
  14. }
  15. //n是有多少个节点,i是对哪个节点做heapify操作
  16. int c1=2*i+1;
  17. int c2=2*i+2;
  18. int max=i;
  19. //在三个值中要找出最大值
  20. if(c1<n&&tree[c1]>tree[max])
  21. {
  22. max=c1;
  23. }
  24. //c1小于n是为了防止越界
  25. if(c2<n&&tree[c2]>tree[max])
  26. {
  27. max=c2;
  28. }
  29. if(max!=i)
  30. {
  31. swap(tree,max,i);//如果max不等于i,那么交换max和i,此时tree[max]
  32. heapify(tree,n,max);//递归,对下一个子节点(即下一个堆的父节点)继续做heapify
  33. }
  34. }
  35. void build_heap(int tree[],int n)
  36. {
  37. int last_node=n-1;//要开始heapify的最后一个节点
  38. int parent=(last_node-1)/2;
  39. int i;
  40. for(i=parent;i>=0;i--)
  41. {
  42. heapify(tree,n,i);
  43. }
  44. }
  45. void heap_sort(int tree[],int n)
  46. {
  47. build_heap(tree,n);
  48. int i;
  49. for(i=n-1;i>=0;i--)
  50. {
  51. swap(tree,i,0);//交换头尾两个数
  52. heapify(tree,i,0);//i代表剩下的节点数量(i不断减少代表着堆的节点不断被砍断)
  53. }
  54. }
  55. int main()
  56. {
  57. int tree[]={
  58. 4,10,3,5,1,2};
  59. int n=6;
  60. heap_sort(tree,n);
  61. int i;
  62. for(i=0;i<n;i++)
  63. {
  64. cout<<tree[i]<<endl;
  65. }
  66. return 0;
  67. }

发表评论

表情:
评论列表 (有 0 条评论,233人围观)

还没有评论,来说两句吧...

相关阅读

    相关 排序算法排序

    一、前言     堆排序是一种选择排序。     选择排序:每趟从待排序的记录中选出关键字最小的记录,顺序放在已排序的记录序列末尾,直到全部排序结束为止。 ----

    相关 排序算法---排序

    二叉堆是完全二叉树或者是近似完全二叉树。 二叉堆满足二个特性: 1.父结点的键值总是大于或等于(小于或等于)任何一个子节点的键值。 2.每个结点的左子树和右子树都是一个二