堆的建立、删除、插入操作以及堆排序
2013-10-29 15:56
381 查看
二叉堆是一种特殊的堆,二叉堆是完全二元树或者是近似完全二元树。
二叉堆有两种:最大堆和最小堆。
最大堆:父结点的键值总是大于或等于任何一个子节点的键值;
最小堆:父结点的键值总是小于或等于任何一个子节点的键值。
堆一般用数组存放:跟节点为0节点,i节点的左子节点为2*i+1,右子节点为2*i+2;
堆的操作: 建立、插入、删除
插入:因为从根节点到叶节点是一个有序序列。将新插入的节点放到最后然后将其放到这个有序序列。
删除:删除某一个节点, 将最后一个节点填充到删除的节点处,然后将此节点看做成根节点构造一个堆。
堆的排序:因为堆的根节点是最小堆值,所以每次取根节点,然后将其删除,剩余的节点重新构造成堆以此递归完成排序。
使用最小堆得到递增序列,最大堆得到递减序列。
由于每次重新恢复堆的时间复杂度为O(logN),共N - 1次重新恢复堆操作,再加上前面建立堆时N / 2次向下调整,每次调整时间复杂度也为O(logN)。二次操作时间相加还是O(N * logN)。故堆排序的时间复杂度为O(N * logN)。下面为代码以最小堆为例:
二叉堆有两种:最大堆和最小堆。
最大堆:父结点的键值总是大于或等于任何一个子节点的键值;
最小堆:父结点的键值总是小于或等于任何一个子节点的键值。
堆一般用数组存放:跟节点为0节点,i节点的左子节点为2*i+1,右子节点为2*i+2;
堆的操作: 建立、插入、删除
插入:因为从根节点到叶节点是一个有序序列。将新插入的节点放到最后然后将其放到这个有序序列。
删除:删除某一个节点, 将最后一个节点填充到删除的节点处,然后将此节点看做成根节点构造一个堆。
堆的排序:因为堆的根节点是最小堆值,所以每次取根节点,然后将其删除,剩余的节点重新构造成堆以此递归完成排序。
使用最小堆得到递增序列,最大堆得到递减序列。
由于每次重新恢复堆的时间复杂度为O(logN),共N - 1次重新恢复堆操作,再加上前面建立堆时N / 2次向下调整,每次调整时间复杂度也为O(logN)。二次操作时间相加还是O(N * logN)。故堆排序的时间复杂度为O(N * logN)。下面为代码以最小堆为例:
#include <iostream> #include <string> #include <algorithm> using namespace std; #define N 1000 int array ; int adjustHeap(int *a, int i, int n) { int j , temp; temp = a[i]; j = 2*i + 1; if(j < n) { if((j+1 < n) && (a[j+1] <= a[j])) { j++; } if(a[j] < temp) { a[i] = a[j]; a[j] = temp; adjustHeap(a, j, n); } } return 1; } //建立最小堆 int buildHeap(int *a, int n) { for(int i = n/2 - 1; i >= 0; i--) adjustHeap(a, i, n); return 1; } //删除节点i int delHeap(int *a, int i, int n) { if(i < n) { swap(a[i], a[n-1]); adjustHeap(a, i, n-1); } return 1; } //插入节点n int insertHeap(int *a, int n) { if(n == 0) return 1; int j = n/2 -1; if(a >= a[j]) return 1; swap(a , a[j]); insertHeap(a, j); return 1; } int sortHeap(int *a, int n) { int i = n; while(i >=0 ) { delHeap(a, 0, i); i--; } return 1; } int main(int argc, char *argv[]) { int a ; int num, i; printf("请输入节点数量: "); scanf("%d", &num); printf("\n请输入%d个节点 以空格结束!\n", num); for(i = 0; i < num; i++) { scanf("%d", &a[i]); } buildHeap(a, num); printf("建成的堆:\n"); for(i = 0; i < num; i++) { printf("%d ", a[i]); } printf("\n"); delHeap(a, 6, num); printf("删除后的堆:\n"); for(i = 0; i < num -1; i++) { printf("%d ", a[i]); } printf("\n"); a[num -1] = 14; insertHeap(a, num-1); printf("插入数据后的堆:\n"); for(i = 0; i < num; i++) { printf("%d ", a[i]); } printf("\n"); sortHeap(a, num); printf("排序后的数据:\n"); for(i = 0; i < num; i++) { printf("%d ", a[i]); } printf("\n"); return 1; }
相关文章推荐
- 实现申请二级域名思路
- Objective-C category (类别) 和 protocol (协议)
- Visual Studio 2012自动添加注释(如版权信息等)
- LINUX下通过外部SMTP发邮件 (直接抛弃sendmail和postfix)
- Osgi环境下解决ClassNotFoundException
- Apple 企业开发者账号&邓白氏码申请记录
- 求教!
- [LeetCode] Plus One
- Android之旅 笔记总结(一)
- 选择排序
- Android之旅 笔记总结(一)
- Objective-C ——dealloc方法(析构方法)
- hibernate session加载实体对象时,将经过哪些过程?
- ARM-LINUX-GCC 4.4.3安装(ubuntu)
- linux串口驱动
- 如何有效抓取SQL Server的BLOCKING信息
- Oracle用户的单张表的读写权限控制
- 支付宝返回参数说明
- linux下解压命令大全
- Objective-C ——一个方法调用另一个方法的简单调用。