大根堆-小根堆-堆排序-C实现
来源:互联网 发布:淘宝提醒发货不见了 编辑:程序博客网 时间:2024/06/05 12:03
大根堆小根堆的实现:以PPT形式呈现大根堆构建的理论过程
1、首先涉及到一个堆的调整,这也是算法的核心部分。假设树中,节点i的子树已经为两个大根堆。这两个子树再加上i节点的话,可能是大根堆也可能不是,因此需要对节点i进行调整。若i小于left(i) or right(i),需要将i下移。
2、这是一个例子,需要将4下移。满足大根堆的性质。
3、大根堆的调整算法。假设i节点的两个子树已经是大根堆。对应代码中MaxHeapify()函数。
4、算法正确性分析。
5、构建大根堆的过程中,只需要考虑n/2 + 1 之前的节点,因为之后的节点都是叶节点。
6、构建大根堆的算法。对应代码中MaxHeapCreat()函数
#include <stdio.h>#include <stdlib.h>#include <stdint.h>#include <assert.h>#include <string.h>/*目的:建立大根堆,也可以变成小根堆,核心:堆的调整输入:一系列来自文件的整数。文件中整数以空格隔开输出:大根堆*/void Swap(uint32_t* array, uint32_t i, uint32_t j){assert(array);uint32_t tmp;tmp = array[j];array[j] = array[i];array[i] = tmp;}/*大根堆调整*/void MaxHeapify(uint32_t* array, uint32_t heapSize, uint32_t currentNode){uint32_t leftChild, rightChild, largest;leftChild = 2*currentNode + 1;rightChild = 2*currentNode + 2;if(leftChild < heapSize && array[leftChild] > array[currentNode])largest = leftChild;elselargest = currentNode;if(rightChild < heapSize && array[rightChild] > array[largest])largest = rightChild;if(largest != currentNode){ Swap(array, largest, currentNode);MaxHeapify(array, heapSize, largest);}}/*构建大根堆*/void MaxHeapCreat(uint32_t* array, uint32_t heapSize){int i;for(i = heapSize/2; i >= 0; i--){MaxHeapify(array, heapSize, i);}}/*小根堆调整*/void MinHeapify(uint32_t* array, uint32_t heapSize, uint32_t currentNode){uint32_t leftChild, rightChild, minimum;leftChild = 2*currentNode + 1;rightChild = 2*currentNode + 2;if(leftChild < heapSize && array[leftChild] < array[currentNode])minimum = leftChild;elseminimum = currentNode;if(rightChild < heapSize && array[rightChild] < array[minimum])minimum = rightChild;if(minimum != currentNode){ Swap(array, minimum, currentNode);MinHeapify(array, heapSize, minimum);}}/*构建小根堆*/void MinHeapCreat(uint32_t* array, uint32_t heapSize){int i;for(i = heapSize/2; i >= 0; i--){MinHeapify(array, heapSize, i);}}int main(){uint32_t tmp;uint32_t *array;array = malloc(sizeof(uint32_t));int i, heapSize = 0;/*从文件中读出待排序数据*/ char* filePathway = "C:/Users/Administrator/Desktop/data.txt"; FILE* fp;fp = fopen(filePathway, "rb");if(!fp){ fprintf(stderr, "Can not open file correctly\n");}while(!feof(fp)){ fscanf(fp, "%d", &tmp); heapSize++; array = realloc(array, sizeof(uint32_t) * (heapSize )); if(array == NULL) { fprintf(stderr, "realloc error!\n"); return 1; } array[heapSize - 1] = tmp; } printf("The origen dataset:\n"); for(i = 0; i < heapSize; i++) { printf("%d\t", array[i]); } printf("\n"); /*构建小根堆并输出*/ MinHeapCreat(array, heapSize); printf("Output the MinHeap:\n"); for(i = 0; i < heapSize; i++) { printf("%d\t", array[i]); } printf("\n"); /*构建大根堆并输出*/ MaxHeapCreat(array, heapSize); printf("Output the MaxHeap:\n"); for(i = 0; i < heapSize; i++) { printf("%d\t", array[i]); } free(array);fclose(fp);return 0;}
这里再加上一个堆的排序算法
首先看一个例子的演示(图片均来自哈工大李建中《算法设计与分析》课件)
通过这个例子不难看出,主要思想是将大根堆的对顶取出,放到数组的最后一个位置,将最后一个位置原来的数放到堆顶,然后对堆顶做调整Max-Heapify(见链接内博客)。
算法伪代码:
重点来啦,直接上代码,代码亲测没有问题的,只是可能得换一下输入数据而已。
#include <stdio.h>#include <stdlib.h>#include <stdint.h>#include <assert.h>#include <string.h>/*目的:建立大根堆,也可以变成小根堆,核心:堆的调整输入:文件,整数以空格隔开输出:大根堆*/void Swap(uint32_t* array, uint32_t i, uint32_t j){assert(array);uint32_t tmp;tmp = array[j];array[j] = array[i];array[i] = tmp;}/*大根堆调整*/void MaxHeapify(uint32_t* array, uint32_t heapSize, uint32_t currentNode){uint32_t leftChild, rightChild, largest;leftChild = 2*currentNode + 1;rightChild = 2*currentNode + 2;if(leftChild < heapSize && array[leftChild] > array[currentNode])largest = leftChild;elselargest = currentNode;if(rightChild < heapSize && array[rightChild] > array[largest])largest = rightChild;if(largest != currentNode){ Swap(array, largest, currentNode);MaxHeapify(array, heapSize, largest);}}/*构建大根堆*/void MaxHeapCreat(uint32_t* array, uint32_t heapSize){int i;for(i = heapSize/2; i >= 0; i--){MaxHeapify(array, heapSize, i);}}/*小根堆调整*/void MinHeapify(uint32_t* array, uint32_t heapSize, uint32_t currentNode){uint32_t leftChild, rightChild, minimum;leftChild = 2*currentNode + 1;rightChild = 2*currentNode + 2;if(leftChild < heapSize && array[leftChild] < array[currentNode])minimum = leftChild;elseminimum = currentNode;if(rightChild < heapSize && array[rightChild] < array[minimum])minimum = rightChild;if(minimum != currentNode){ Swap(array, minimum, currentNode);MinHeapify(array, heapSize, minimum);}}/*构建小根堆*/void MinHeapCreat(uint32_t* array, uint32_t heapSize){int i;for(i = heapSize/2; i >= 0; i--){MinHeapify(array, heapSize, i);}}void HeapSort(uint32_t* array, uint32_t heapSize){ MaxHeapCreat(array, heapSize); int i; uint32_t arraySize = heapSize; for(i = arraySize - 1; i >= 1; i--) { Swap(array, 0, i); heapSize--; MaxHeapify(array, heapSize, 0); }}int main(){uint32_t tmp;uint32_t *array;array = malloc(sizeof(uint32_t));int i, heapSize = 0;/*从文件中读出待排序数据*/ char* filePathway = "C:/Users/Administrator/Desktop/data.txt"; FILE* fp;fp = fopen(filePathway, "rb");if(!fp){ fprintf(stderr, "Can not open file correctly\n");}while(!feof(fp)){ fscanf(fp, "%d", &tmp); heapSize++; array = realloc(array, sizeof(uint32_t) * (heapSize )); if(array == NULL) { fprintf(stderr, "realloc error!\n"); return 1; } array[heapSize - 1] = tmp; } printf("The origen dataset:\n"); for(i = 0; i < heapSize; i++) { printf("%d\t", array[i]); } printf("\n"); /*构建小根堆并输出*/ MinHeapCreat(array, heapSize); printf("Output the MinHeap:\n"); for(i = 0; i < heapSize; i++) { printf("%d\t", array[i]); } printf("\n"); /*构建大根堆并输出*/ MaxHeapCreat(array, heapSize); printf("Output the MaxHeap:\n"); for(i = 0; i < heapSize; i++) { printf("%d\t", array[i]); } /*堆排序*/ HeapSort(array, heapSize); printf("Output the SortedHeap:\n"); for(i = 0; i < heapSize; i++) { printf("%d\t", array[i]); } free(array);fclose(fp);return 0;}
0 0
- 大根堆-小根堆-堆排序-C实现
- 堆排序的C实现
- 堆排序C语言实现
- 堆排序C语言实现
- 堆排序C语言实现
- 堆排序C语言实现
- 堆排序--C语言实现
- C语言实现堆排序
- 堆排序(c实现)
- 堆排序--C语言实现
- 堆排序C语言实现
- 堆排序的实现(c++)
- C实现heap堆排序
- c/c++实现堆排序
- 堆排序C语言实现
- C语言实现堆排序
- 堆排序c语言实现
- 堆排序-C语言实现
- java 单链集合实现
- Java基础---网络编程
- WIFI基本知识整理
- 使用 EhCache 关于临时目录的一个注意事项
- Effective C++ 条款27
- 大根堆-小根堆-堆排序-C实现
- frame,iframe,frameset之间的关系与区别
- 黑马程序员----多态和内部类、异常
- 设置环境变量的三种方法
- 【MySQL】常见的mysql 进程state
- android开发中的自定义属性用法详解
- php 异步上传原理(iframe)
- codeforces #310 B B. Case of Fugitive(贪心)
- 共同父域下的单点登录