-
Notifications
You must be signed in to change notification settings - Fork 14.8k
feat(heap): add c codes. #261
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from all commits
Commits
Show all changes
2 commits
Select commit
Hold shift + click to select a range
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,2 @@ | ||
| add_executable(my_heap my_heap.c) | ||
|
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,185 @@ | ||
| /** | ||
| * File: my_heap.c | ||
| * Created Time: 2023-01-15 | ||
| * Author: Reanon ([email protected]) | ||
| */ | ||
|
|
||
| #include "../include/include.h" | ||
|
|
||
| #define MAX_SIZE 5000 | ||
|
|
||
| // 大顶堆 | ||
| typedef struct maxHeap { | ||
| // size 代表的是实际元素的个数 | ||
| int size; | ||
| // 使用预先分配内存的数组,避免扩容 | ||
| int data[MAX_SIZE]; | ||
| } maxHeap; | ||
|
|
||
| void siftDown(maxHeap *h, int i); | ||
|
|
||
| void siftUp(maxHeap *h, int i); | ||
krahets marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
|
||
| /* 构造空堆 */ | ||
| maxHeap *newEmptyMaxHeap() { | ||
| // 所有元素入堆 | ||
| maxHeap *h = (maxHeap *) malloc(sizeof(maxHeap)); | ||
| h->size = 0; | ||
| return h; | ||
| } | ||
|
|
||
| /* 构造函数,根据切片建堆 */ | ||
| maxHeap *newMaxHeap(int nums[], int size) { | ||
krahets marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| // 所有元素入堆 | ||
| maxHeap *h = (maxHeap *) malloc(sizeof(maxHeap)); | ||
| h->size = size; | ||
| memcpy(h->data, nums, size * sizeof(int)); | ||
| for (int i = size - 1; i >= 0; i--) { | ||
| // 堆化除叶结点以外的其他所有结点 | ||
| siftDown(h, i); | ||
| } | ||
| return h; | ||
| } | ||
|
|
||
| /* 获取左子结点索引 */ | ||
| int left(maxHeap *h, int i) { | ||
| return 2 * i + 1; | ||
| } | ||
|
|
||
| /* 获取右子结点索引 */ | ||
| int right(maxHeap *h, int i) { | ||
| return 2 * i + 2; | ||
| } | ||
|
|
||
| /* 获取父结点索引 */ | ||
| int parent(maxHeap *h, int i) { | ||
| return (i - 1) / 2; | ||
| } | ||
|
|
||
| /* 交换元素 */ | ||
| int swap(maxHeap *h, int i, int j) { | ||
| int temp = h->data[i]; | ||
| h->data[i] = h->data[j]; | ||
| h->data[j] = temp; | ||
| } | ||
|
|
||
| /* 获取堆大小 */ | ||
| int size(maxHeap *h) { | ||
| return h->size; | ||
| } | ||
|
|
||
| /* 判断堆是否为空 */ | ||
| int isEmpty(maxHeap *h) { | ||
| return h->size == 0; | ||
| } | ||
|
|
||
| /* 访问堆顶元素 */ | ||
| int peek(maxHeap *h) { | ||
| return h->data[0]; | ||
| } | ||
|
|
||
| /* 元素入堆 */ | ||
| int push(maxHeap *h, int val) { | ||
| // 默认情况下,不应该添加这么多结点 | ||
| if (h->size == MAX_SIZE) { | ||
| printf("heap is full!"); | ||
| return NIL; | ||
| } | ||
| // 添加结点 | ||
| h->data[h->size] = val; | ||
| h->size++; | ||
|
|
||
| // 从底至顶堆化 | ||
| siftUp(h, h->size - 1); | ||
| } | ||
|
|
||
| /* 元素出堆 */ | ||
| int poll(maxHeap *h) { | ||
| // 判空处理 | ||
| if (isEmpty(h)) { | ||
| printf("heap is empty!"); | ||
| return NIL; | ||
| } | ||
| // 交换根结点与最右叶结点(即交换首元素与尾元素) | ||
| swap(h, 0, size(h) - 1); | ||
| // 删除结点 | ||
| int val = h->data[h->size - 1]; | ||
| h->size--; | ||
| // 从顶至底堆化 | ||
| siftDown(h, 0); | ||
|
|
||
| // 返回堆顶元素 | ||
| return val; | ||
| } | ||
|
|
||
|
|
||
| /* 从结点 i 开始,从顶至底堆化 */ | ||
| void siftDown(maxHeap *h, int i) { | ||
| while (true) { | ||
| // 判断结点 i, l, r 中值最大的结点,记为 max | ||
| int l = left(h, i); | ||
| int r = right(h, i); | ||
| int max = i; | ||
| if (l < size(h) && h->data[l] > h->data[max]) { | ||
| max = l; | ||
| } | ||
| if (r < size(h) && h->data[r] > h->data[max]) { | ||
| max = r; | ||
| } | ||
| // 若结点 i 最大或索引 l, r 越界,则无需继续堆化,跳出 | ||
| if (max == i) { | ||
| break; | ||
| } | ||
| // 交换两结点 | ||
| swap(h, i, max); | ||
| // 循环向下堆化 | ||
| i = max; | ||
| } | ||
| } | ||
|
|
||
| /* 从结点 i 开始,从底至顶堆化 */ | ||
| void siftUp(maxHeap *h, int i) { | ||
| while (true) { | ||
| // 获取结点 i 的父结点 | ||
| int p = parent(h, i); | ||
| // 当“越过根结点”或“结点无需修复”时,结束堆化 | ||
| if (p < 0 || h->data[i] <= h->data[p]) { | ||
| break; | ||
| } | ||
| // 交换两结点 | ||
| swap(h, i, p); | ||
| // 循环向上堆化 | ||
| i = p; | ||
| } | ||
| } | ||
|
|
||
| int main() { | ||
| /* 初始化堆 */ | ||
| // 初始化大顶堆 | ||
| int nums[] = {9, 8, 6, 6, 7, 5, 2, 1, 4, 3, 6, 2}; | ||
| maxHeap *heap = newMaxHeap(nums, sizeof(nums) / sizeof(int)); | ||
| printf("输入数组并建堆后\n"); | ||
| printHeap(heap->data, heap->size); | ||
|
|
||
| /* 获取堆顶元素 */ | ||
| printf("\n堆顶元素为 %d\n", peek(heap)); | ||
|
|
||
| /* 元素入堆 */ | ||
| push(heap, 7); | ||
| printf("\n元素 7 入堆后\n"); | ||
| printHeap(heap->data, heap->size); | ||
|
|
||
| /* 堆顶元素出堆 */ | ||
| int top = poll(heap); | ||
| printf("\n堆顶元素 %d 出堆后\n", top); | ||
| printHeap(heap->data, heap->size); | ||
|
|
||
| /* 获取堆大小 */ | ||
| printf("\n堆元素数量为 %d\n", size(heap)); | ||
|
|
||
| /* 判断堆是否为空 */ | ||
| printf("\n堆是否为空 %d\n", isEmpty(heap)); | ||
|
|
||
| // 释放内存 | ||
| free(heap); | ||
krahets marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| } | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.