OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 2155|回复: 0

C语言实现堆数据结构和基本操作

[复制链接]

15

主题

68

帖子

0

精华

新手上路

积分
29
金钱
29
注册时间
2016-9-10
在线时间
104 小时
发表于 2022-6-16 14:41:31 | 显示全部楼层 |阅读模式
本帖最后由 lccpcc 于 2022-6-16 22:12 编辑
  1. #include <stdlib.h>
  2. #include <stdbool.h>
  3. #include <assert.h>
  4. #include <string.h>

  5. typedef int HPDateType;

  6. typedef struct Heap
  7. {
  8.     HPDateType *a;
  9.     int size;
  10.     int capacity;
  11. } HP;

  12. void HeapInit(HP *php, HPDateType *a, int n);
  13. void HeapDestroy(HP *php);                    
  14. void HeapPush(HP *php, HPDateType x);     
  15. void HeapPop(HP *php);                       
  16. HPDateType HeapTop(HP *php);              
  17. int HeapSize(HP *php);                     
  18. bool HeapEmpty(HP *php);                 
  19. void HeapPrint(HP *php);                  
  20. void AdjustUp(HP *st, int child);         
  21. void AdjustDown(HP *st, int praent);           
  22. void Swap(int *p1, int *p2);               
  23. void HeapSort(HP *php);                  


  24. </div><div yne-bulb-block="code" data-theme="default" style="white-space:pre-wrap;" data-language="c">int main(int argc, char **argv)
  25. {
  26.     HP st;
  27.     int a[] = {15, 18, 28, 34, 65, 19, 49, 25, 37, 27};
  28.     int n = sizeof(a) / sizeof(a[0]);

  29.     printf("\ntest HeapInit(), HeapPrint():\n");
  30.     HeapInit(&st, a, n);
  31.     HeapPrint(&st);

  32.     printf("\ntest HeapPush(&st, 8):\n");
  33.     HeapPush(&st, 8);
  34.     HeapPrint(&st);

  35.     printf("\ntest HeapPush(&st, 88):\n");
  36.     HeapPush(&st, 88);
  37.     HeapPrint(&st);

  38.     printf("\ntest HeapPop(&st):\n");
  39.     HeapPop(&st);
  40.     HeapPrint(&st);

  41.     printf("\ntest HeapPop(&st):\n");
  42.     HeapPop(&st);
  43.     HeapPrint(&st);

  44.     printf("\n对堆进行排序:\n");
  45.     HeapSort(&st);
  46.     HeapPrint(&st);


  47.     /* 销毁堆 */
  48.     HeapDestroy(&st);

  49.     if(st.a == NULL)
  50.         printf("\n销毁堆成功\n");

  51.     return 0;
  52. }

  53. // 交换
  54. void Swap(int *p1, int *p2)
  55. {
  56.     int temp = *p1;
  57.     *p1 = *p2;
  58.     *p2 = temp;
  59. }

  60. // 向上调整算法
  61. void AdjustUp(HP *st, int child)
  62. {
  63.     int parent = (child - 1) / 2;

  64.     while (child > 0)
  65.     {
  66.         if (st->a[child] < st->a[parent])
  67.         {
  68.             Swap(&st->a[child], &st->a[parent]);
  69.             child = parent;
  70.             parent = (child - 1) / 2;
  71.         }
  72.         else
  73.         {
  74.             break;
  75.         }
  76.     }
  77. }

  78. // 向下调整算法
  79. void AdjustDown(HP *st, int praent)
  80. {
  81.     int child = praent * 2 + 1;

  82.     while (child < st->size)
  83.     {
  84.         if (child + 1 < st->size && st->a[child + 1] < st->a[child])
  85.         {
  86.             child++;
  87.         }

  88.         if (st->a[child] < st->a[praent])
  89.         {
  90.             Swap(&st->a[child], &st->a[praent]);
  91.             praent = child;
  92.             child = praent * 2 + 1;
  93.         }
  94.         else
  95.         {
  96.             break;
  97.         }
  98.     }
  99. }

  100. void HeapInit(HP *php, HPDateType *a, int n)
  101. {
  102.     if (php == NULL)
  103.         return;

  104.     php->a = (HPDateType *)calloc(1, sizeof(HPDateType) * n);

  105.     if (php->a == NULL)
  106.         exit(EXIT_FAILURE);

  107.     memcpy(php->a, a, sizeof(HPDateType) * n);
  108.     php->capacity = n;
  109.     php->size = n;

  110.     int i;

  111.     //建小堆
  112.     for (i = (php->size - 2) / 2; i >= 0; i--)
  113.         AdjustDown(php, i);
  114. }

  115. void HeapDestroy(HP *php)
  116. {
  117.     if (php == NULL)
  118.         return;

  119.     free(php->a);
  120.     php->a = NULL;
  121.     php->size = 0;
  122.     php->capacity = 0;
  123. }

  124. //在堆里面插入一个数,并且让它的结构还是一个堆
  125. void HeapPush(HP *php, HPDateType x)
  126. {
  127.     if (php == NULL)
  128.         return;

  129.     /* 如果堆的空间满了,就用realloc()重新扩大堆的数组空间的大小 */
  130.     if (php->size == php->capacity)
  131.     {
  132.         HPDateType *temp = (HPDateType *)realloc(php->a, sizeof(HPDateType) * php->capacity * 2);
  133.         if (temp == NULL)
  134.             exit(EXIT_FAILURE);

  135.         php->a = temp;
  136.         php->capacity = php->capacity * 2;
  137.     }

  138.     php->a[php->size] = x;
  139.     php->size++;

  140.     AdjustUp(php, php->size - 1);
  141. }

  142. //删除堆的顶的数据,并且让它的结构还是一个堆
  143. void HeapPop(HP *php)
  144. {
  145.     if (php == NULL)
  146.         return;

  147.     if (HeapEmpty(php))
  148.         return;

  149.     int end = php->size - 1;

  150.     Swap(&php->a[0], &php->a[end]);
  151.     php->size--;

  152.     AdjustDown(php, 0);
  153. }

  154. //返回堆顶的数据
  155. HPDateType HeapTop(HP *php)
  156. {
  157.     if (php == NULL)
  158.         return;

  159.     if (HeapEmpty(php))
  160.         return;

  161.     return php->a[0];
  162. }

  163. //返回堆里面数据的个数
  164. int HeapSize(HP *php)
  165. {
  166.     if (php == NULL)
  167.         return;

  168.     return php->size;
  169. }

  170. //判断堆是否为空
  171. bool HeapEmpty(HP *php)
  172. {
  173.     if (php == NULL)
  174.         return;
  175.     return (php->size == 0);
  176. }

  177. //将堆打印出来
  178. void HeapPrint(HP *php)
  179. {
  180.     int i;
  181.     int m = 1, n = 0;

  182.     printf("\n从上到下输出堆的内容:\n");

  183.     for (i = 0; i < php->size; i++)
  184.     {
  185.         printf("%d ", php->a[i]);
  186.         if (i == n)
  187.         {
  188.             putchar('\n');
  189.             m = m * 2;
  190.             n += m;
  191.         }
  192.     }

  193.     printf("\n\n");
  194. }

  195. void HeapSort(HP *php)
  196. {
  197.     int t = php->size;

  198.     while (php->size != 0)
  199.     {
  200.         HeapPop(php);
  201.     }

  202.     php->size = t;
  203. }
  204. </div></article>
复制代码
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2024-6-9 06:07

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

快速回复 返回顶部 返回列表