赞
踩
本文目录
本文章主要讲解二叉树的顺序结构及实现方式,想了解树的基本概念的,请移步数据结构----树
int array[] = {27,15,19,18,28,34,65,49,25,37};
int a[] = {1,5,3,8,7,6};
在了解堆的基本实现逻辑后,就可以试着实现整个代码了
- typedef int HPDataType;
-
- typedef struct Heap
- {
- HPDataType* a;
- size_t size;
- size_t capacity;
- }HP;
- void HeapInit(HP* php)
- {
- assert(php);
-
- php->a = NULL;
- php->capacity = php->size = 0;
- }
- void HeapDestroy(HP* php)
- {
- assert(php);
-
- free(php->a);
- php->a = NULL;
-
- php->capacity = php->size = 0;
- }
- void HeapPrint(HP* php)
- {
- assert(php);
-
- for (size_t i = 0; i < php->size; ++i)
- {
- printf("%d ", php->a[i]);
- }
-
- printf("\n");
- }
- void Swap(HPDataType* pa, HPDataType* pb)
- {
- HPDataType tmp = *pa;
- *pa = *pb;
- *pb = tmp;
- }
- void AdjustUp(HPDataType* a, size_t child)
- {
- size_t parent = (child - 1) / 2;
-
- while (child > 0)
- {
- if (a[child] < a[parent])
- {
- Swap(&a[child], &a[parent]);
- child = parent;
- parent = (child - 1) / 2;
- }
- else
- {
- break;
- }
- }
- }
- void AdjustDown(HPDataType* a, size_t size, size_t root)
- {
- size_t parent = root;
- size_t child = parent * 2 + 1;
-
- while (child < size)
- {
- if (child + 1 < size && a[child] > a[child + 1])
- {
- child++;
- }
-
- if (a[child] < a[parent])
- {
- Swap(&a[child], &a[parent]);
- parent = child;
- child = parent * 2 + 1;
- }
- else
- {
- break;
- }
- }
- }
- void HeapPush(HP* php, HPDataType x)
- {
- assert(php);
-
- if (php->size == php->capacity)
- {
- size_t newCapacity = php->capacity == 0 ? 4 : php->capacity * 2;
- HPDataType* tmp = realloc(php->a, sizeof(HPDataType) * newCapacity);
- if (tmp == NULL)
- {
- printf("realloc failed\n");
- exit(-1);
- }
-
- php->a = tmp;
- php->capacity = newCapacity;
- }
-
- php->a[php->size] = x;
- ++php->size;
-
- AdjustUp(php->a, php->size - 1);
- }
- void HeapPop(HP* php)
- {
- assert(php);
- assert(php->size > 0);
-
- Swap(&php->a[0], &php->a[php->size - 1]);
- --php->size;
-
- AdjustDown(php->a, php->size, 0);
- }
- bool HeapEmpty(HP* php)
- {
- assert(php);
-
- return php->size == 0;
- }
- size_t HeapSize(HP* php)
- {
- assert(php);
-
- return php->size;
- }
- HPDataType HeapTop(HP* php)
- {
- assert(php);
- assert(php->size > 0);
-
- return php->a[0];
- }
在我们实现堆后,堆可以用来解决一些实际问题
1. 建堆
2. 利用堆删除思想来进行排序
- void HeapSort(int* a, int n)
- {
- // 向上调整建堆 O(N*logN)
- /*for (int i = 1; i < n; i++)
- {
- AdjustUp(a, n);
- }*/
-
- // 向下调整建堆 O(N)
- for (int i = (n - 1 - 1) / 2; i >= 0; i--)
- {
- AdjustDown(a, n, i);
- }
-
- int j = n;
- while (--j)
- {
- Swap(&a[0], &a[j]);
- AdjustDown(a, j, 0);
- }
- }
- void PrintTopK(int* a, int n, int k)
- {
-
- // 1. 建堆--用a中前k个元素建堆
- int* kminHeap = (int*)malloc(sizeof(int) * k);
- assert(kminHeap);
- for (int i = 0; i < k; ++i)
- {
- kminHeap[i] = a[i];
- }
- //建小堆
- for (int j = (k - 1 - 1) / 2; j >= 0; --j)
- {
- AdjustDown(a, k, j);
- }
-
- // 2. 将剩余n-k个元素依次与堆顶元素交换,不满则则替换
- for (int i = k; i < n; ++i)
- {
- if (a[i] > kminHeap[0])
- {
- kminHeap[0] = a[i];
- AdjustDown(kminHeap, k, 0);
- }
- }
- for (int j = 0; j< k; ++j)
- {
- printf("%d ", kminHeap[j]);
- }
- printf("\n");
- free(kminHeap);
- }
-
- void TestTopk()
- {
- int n = 10000;
- int* a = (int*)malloc(sizeof(int)*n);
- srand(time(0));
- for (size_t i = 0; i < n; ++i)
- {
- a[i] = rand() % 1000000;
- }
- a[5] = 1000000 + 1;
- a[1231] = 1000000 + 2;
- a[531] = 1000000 + 3;
- a[5121] = 1000000 + 4;
- a[115] = 1000000 + 5;
- a[2335] = 1000000 + 6;
- a[9999] = 1000000 + 7;
- a[76] = 1000000 + 8;
- a[423] = 1000000 + 9;
- a[3144] = 1000000 + 10;
-
- PrintTopK(int* a, n, 10);
- }
我们来建立一个test函数来测试一下,这需要调用之前我们所定义的相关函数。
- void test()
- {
- HP hp;
- HeapInit(&hp);
-
- HeapPush(&hp, 1);
- HeapPush(&hp, 5);
- HeapPush(&hp, 0);
- HeapPush(&hp, 8);
- HeapPush(&hp, 3);
- HeapPush(&hp, 9);
- HeapPrint(&hp);
-
-
- HeapPop(&hp);
- HeapPrint(&hp);
-
- HeapDestroy(&hp);
- }
- #pragma once
-
- // 小堆
- #include<stdio.h>
- #include<assert.h>
- #include<stdlib.h>
- #include<stdbool.h>
-
- typedef int HPDataType;
-
- typedef struct Heap
- {
- HPDataType* a;
- size_t size;
- size_t capacity;
- }HP;
-
- void Swap(HPDataType* pa, HPDataType* pb);
- void HeapInit(HP* php);
- void HeapDestroy(HP* php);
- void HeapPrint(HP* php);
-
- // 插入x以后,保持他依旧是(大/小)堆
- void HeapPush(HP* php, HPDataType x);
-
- // 删除堆顶的数据。(最小/最大)
- void HeapPop(HP* php);
- bool HeapEmpty(HP* php);
- size_t HeapSize(HP* php);
- HPDataType HeapTop(HP* php);
- #include "Heap.h"
-
- void Swap(HPDataType* pa, HPDataType* pb)
- {
- HPDataType tmp = *pa;
- *pa = *pb;
- *pb = tmp;
- }
-
- void HeapInit(HP* php)
- {
- assert(php);
-
- php->a = NULL;
- php->capacity = php->size = 0;
- }
-
- void HeapDestroy(HP* php)
- {
- assert(php);
-
- free(php->a);
- php->a = NULL;
-
- php->capacity = php->size = 0;
- }
-
- void HeapPrint(HP* php)
- {
- assert(php);
-
- for (size_t i = 0; i < php->size; ++i)
- {
- printf("%d ", php->a[i]);
- }
-
- printf("\n");
- }
-
- void AdjustUp(HPDataType* a, size_t child)
- {
- size_t parent = (child - 1) / 2;
-
- while (child > 0)
- {
- if (a[child] < a[parent])
- {
- Swap(&a[child], &a[parent]);
- child = parent;
- parent = (child - 1) / 2;
- }
- else
- {
- break;
- }
- }
- }
-
- void HeapPush(HP* php, HPDataType x)
- {
- assert(php);
-
- if (php->size == php->capacity)
- {
- size_t newCapacity = php->capacity == 0 ? 4 : php->capacity * 2;
- HPDataType* tmp = realloc(php->a, sizeof(HPDataType) * newCapacity);
- if (tmp == NULL)
- {
- printf("realloc failed\n");
- exit(-1);
- }
-
- php->a = tmp;
- php->capacity = newCapacity;
- }
-
- php->a[php->size] = x;
- ++php->size;
-
- AdjustUp(php->a, php->size - 1);
- }
-
- void AdjustDown(HPDataType* a, size_t size, size_t root)
- {
- size_t parent = root;
- size_t child = parent * 2 + 1;
-
- while (child < size)
- {
- if (child + 1 < size && a[child] > a[child + 1])
- {
- child++;
- }
-
- if (a[child] < a[parent])
- {
- Swap(&a[child], &a[parent]);
- parent = child;
- child = parent * 2 + 1;
- }
- else
- {
- break;
- }
- }
- }
-
- void HeapPop(HP* php)
- {
- assert(php);
- assert(php->size > 0);
-
- Swap(&php->a[0], &php->a[php->size - 1]);
- --php->size;
-
- AdjustDown(php->a, php->size, 0);
- }
-
- bool HeapEmpty(HP* php)
- {
- assert(php);
-
- return php->size == 0;
- }
-
- size_t HeapSize(HP* php)
- {
- assert(php);
-
- return php->size;
- }
-
- HPDataType HeapTop(HP* php)
- {
- assert(php);
- assert(php->size > 0);
-
- return php->a[0];
- }
- #include "Heap.h"
-
- void test()
- {
- HP hp;
- HeapInit(&hp);
-
- HeapPush(&hp, 1);
- HeapPush(&hp, 5);
- HeapPush(&hp, 0);
- HeapPush(&hp, 8);
- HeapPush(&hp, 3);
- HeapPush(&hp, 9);
- HeapPrint(&hp);
-
-
- HeapPop(&hp);
- HeapPrint(&hp);
-
- HeapDestroy(&hp);
- }
-
- void HeapSort(int* a, int size)
- {
- HP hp;
- HeapInit(&hp);
-
- for (int i = 0; i < size; ++i)
- {
- HeapPush(&hp, a[i]);
- }
-
- int j = 0;
- while (!HeapEmpty(&hp))
- {
- a[j++] = HeapTop(&hp);
- HeapPop(&hp);
- }
-
- HeapDestroy(&hp);
- }
-
- int main()
- {
- test();
-
- int a[] = { 4, 2, 7, 8, 5, 1, 0, 6 };
- HeapSort(a, sizeof(a) / sizeof(int));
-
- for (int i = 0; i < sizeof(a) / sizeof(int); ++i)
- {
- printf("%d ", a[i]);
- }
- printf("\n");
-
- return 0;
- }
后续内容,等博主继续学习后分享给大家。请大家继续关注,不断督促,共同进步!
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。