二叉堆 - 最大堆

与上篇《二叉堆 - 最小堆》类似,只不过堆序(heap order)从内部节点小于左右子节点变成了内部节点大于左右子节点。

代码如下:

  1 #include <cstdio>
  2 #include <cstdlib>
  3
  4 #define MIN (1<<(sizeof(int)*8-1))
  5 #define MAX (~MIN)
  6
  7 typedef int Item;
  8 typedef struct HeapStruct* heap;
  9
 10 struct HeapStruct {
 11     int capacity;  // capacity的大小为堆的元素加1。
 12     int size;      // size指向堆中最后一个元素,size=0时堆为空
 13     Item* items;   // items的第一个元素存放sentinel,其余元素存放堆中内容。
 14 };
 15 // 初始化堆的三个参数
 16 heap
 17 InitHeap(int maxItems)
 18 {
 19     heap h;
 20
 21     h = (heap)malloc(sizeof(struct HeapStruct));
 22     if (h == NULL) {
 23         printf("out of space.\n");
 24         return NULL;
 25     }
 26
 27     h->items =(Item*)malloc((maxItems+1)*sizeof(Item)); // 用h->items[0]来存放sentinel
 28     if (h->items == NULL) {
 29         printf("out of space.\n");
 30         return NULL;
 31     }
 32
 33     h->capacity = maxItems;
 34     h->size = 0;
 35     h->items[0] = MAX;
 36
 37     return h;
 38 }
 39
 40 int
 41 IsFull(heap h)
 42 {
 43     if (h->size == h->capacity) {
 44         return 1;
 45     } else {
 46         return 0;
 47     }
 48 }
 49
 50 int
 51 IsEmpty(heap h)
 52 {
 53     if (h->size == 0) {
 54         return 1;
 55     } else {
 56         return 0;
 57     }
 58 }
 59
 60 Item
 61 FindMax(heap h)
 62 {
 63     return h->items[1];
 64 }
 65 // 向最大堆插入元素。
 66 void
 67 Insert(Item item, heap h)
 68 {
 69     if (IsFull(h)) {
 70         printf("Insert failed. Because the heap is full.\n");
 71         return;
 72     }
 73     // percolate up,将item往上,一步一步放到合适的地方。
 74     int i;
 75     for (i = ++h->size; h->items[i/2] < item; i /= 2) {
 76         h->items[i] = h->items[i/2];
 77     }
 78     h->items[i] = item;
 79 }
 80 // 在最大堆中删除元素。 返回最大值。
 81 Item
 82 DeleteMax(heap h)
 83 {
 84     if (IsEmpty(h)) {
 85         printf("Delete failed. Because the heap is empty.\n");
 86         return h->items[0];
 87     }
 88
 89     Item maxItem = h->items[1];
 90     Item lastItem = h->items[h->size--]; // 此函数目的就是把lastItem放到合适位置
 91     // percolate down,将lastItem往下,一步一步往下寻找合适的地方。
 92     int i, child;
 93     for (i = 1; 2*i <= h->size; i = child) {
 94         child = 2 * i;
 95         // 将child放在左右子树中较大的那个位置上
 96         if (child != h->size && h->items[child] < h->items[child+1]) {
 97             child++;
 98         }
 99
100         if (lastItem < h->items[child]) {
101             h->items[i] = h->items[child];
102         } else {
103             break;
104         }
105     }
106     h->items[i] = lastItem;
107     return maxItem;
108 }
109 // 以插入的方式来建堆。复杂度为O(NlogN),因为有N个元素,每次插入花费logN时间。
110 void
111 BuildHeap(heap h, Item arr[], int len)
112 {
113     for (int i = 0; i < len; i++) {
114         Insert(arr[i], h);
115     }
116 }
117 // 以下滤的方式来建堆(对已有的数组进行排序,使之符合最大堆的堆序heap order)。
118 // 参数i为数组对应的二叉堆的内部节点,下滤操作将之放到比左右子节点都大的位置上。
119 void
120 PercDown(heap h, int i)
121 {
122     int child;
123     int tmp;
124
125     for (tmp = h->items[i]; 2*i <= h->size; i = child) {
126         child = 2*i;
127         if (child != h->size && h->items[child] < h->items[child+1]) {
128             child++;
129         }
130         if (tmp < h->items[child]) {
131             h->items[i] = h->items[child];
132         } else {
133             break;
134         }
135     }
136     h->items[i] = tmp;
137 }
138
139 int
140 main(int argc, char** argv)
141 {
142     int arr[6] = {17, 11, 2, 23, 5, 7};
143
144     heap h;
145     h = InitHeap(6);
146     //BuildHeap(h, arr, 6);
147
148     // build heap
149     for (int i = 0; i < 6; i++) {
150         h->items[++h->size] = arr[i];
151
152     }
153     for (int i = 6/2; i > 0; i--) {
154         PercDown(h, i);
155     }
156
157     for (int i = 1; i <= h->size; i++) {
158         printf("%d\t", h->items[i]);
159     }
160     printf("\n");
161
162     // test DeleteMin, out put a sorted array
163     int sortedArr[6] = {0};
164     for (int i = 0; i < 6; i++) {
165         sortedArr[i] = DeleteMax(h);
166     }
167     for (int i = 0; i < 6; i++) {
168         printf("%d\t", sortedArr[i]);
169     }
170     printf("\n");
171
172     system("pause");
173
174     return 0;
175 }
时间: 2024-08-03 06:07:19

二叉堆 - 最大堆的相关文章

堆排序:什么是堆?什么是最大堆?二叉堆是什么?堆排序算法是怎么样的?PHP如何实现堆排序?

本文标签:  堆排序 php php算法 堆排序算法 二叉堆 数据结构 REST   服务器 什么是堆 这里的堆(二叉堆),指得不是堆栈的那个堆,而是一种数据结构. 堆可以视为一棵完全的二叉树,完全二叉树的一个"优秀"的性质是,除了最底层之外,每一层都是满的,这使得堆可以利用数组来表示,每一个结点对应数组中的一个元素. 数组与堆之间的关系 二叉堆一般分为两种:最大堆和最小堆. 什么是最大堆 堆中每个父节点的元素值都大于等于其孩子结点(如果存在),这样的堆就是一个最大堆 因此,最大堆中的

二叉堆(binary heap)

堆(heap) 亦被称为:优先队列(priority queue),是计算机科学中一类特殊的数据结构的统称.堆通常是一个可以被看做一棵树的数组对象.在队列中,调度程序反复提取队列中第一个作业并运行,因而实际情况中某些时间较短的任务将等待很长时间才能结束,或者某些不短小,但具有重要性的作业,同样应当具有优先权.堆即为解决此类问题设计的一种数据结构. 本文地址:http://www.cnblogs.com/archimedes/p/binary-heap.html,转载请注明源地址. 逻辑定义 n个

二叉堆 - 最小堆

二叉堆:一般我们拿来用的就是最大堆和最小堆. 最小堆:每个节点的值比它的左右子节点的值要大. 代码实现如下:参考Mark Allen Weiss<数据结构和算法分析>(第二版) 1 #include <cstdio> 2 #include <cstdlib> 3 4 #define MIN (1<<(sizeof(int)*8-1)) 5 6 typedef int Item; 7 typedef struct HeapStruct* heap; 8 9 s

堆、二叉堆、堆排序

堆.二叉堆.堆排序 堆的概念: n个元素序列 { k1, k2, k3, k4, k5, k6 -. kn } 当且仅当满足以下关系时才会被称为堆: ki <= k2i,ki <= k2i+1 或者 ki >= k2i,ki >= k2i+1 (i = 1,2,3,4 .. n/2) 如果数组的下表是从0开始,那么需要满足 ki <= k2i+1,ki <= k2i+2 或者 ki >= k2i+1,ki >= k2i+2 (i = 0,1,2,3 .. n

堆之二叉堆

堆的定义 堆通常是一个可以被看做一棵树,它满足下列性质: 堆中任意节点的值总是不大于(不小于)其子节点的值: 堆总是一棵完全树. 将任意节点不大于其子节点的堆叫做最小堆或小根堆,而将任意节点不小于其子节点的堆叫做最大堆或大根堆.常见的堆有二叉堆.左倾堆.斜堆.二项堆.斐波那契堆等等. 二叉堆 堆有两种性质:结构性和堆序性 结构性:堆是一颗完全二叉树.若设完全二叉树的高度是h,则它的节点数是2^h到2^(h+1) - 1:则节点数为N的完全二叉树的高度O(logn). 完全二叉树中父子节点位置关系

笔试算法题(46):简介 - 二叉堆 &amp; 二项树 &amp; 二项堆 &amp; 斐波那契堆

二叉堆(Binary Heap) 二叉堆是完全二叉树(或者近似完全二叉树):其满足堆的特性:父节点的值>=(<=)任何一个子节点的键值,并且每个左子树或者右子树都是一 个二叉堆(最小堆或者最大堆):一般使用数组构建二叉堆,对于array[i]而言,其左子节点为array[2*i],其右子节点为 array[2*i+1]:二叉堆支持插入,删除,查找最大(最小)键值的操作,但是合并二叉堆的复杂度较高,时间复杂度为O(N):但是二项堆或者斐波 那契堆则仅需要O(logN): 二项树(Binomial

【数据结构】二叉堆

看到一篇很好的博文,来自http://blog.csdn.net/morewindows/article/details/6709644 下面是博文内容 堆排序与快速排序,归并排序一样都是时间复杂度为O(N*logN)的几种常见排序方法.学习堆排序前,先讲解下什么是数据结构中的二叉堆. 二叉堆的定义 二叉堆是完全二叉树或者是近似完全二叉树. 二叉堆满足二个特性: 1.父结点的键值总是大于或等于(小于或等于)任何一个子节点的键值. 2.每个结点的左子树和右子树都是一个二叉堆(都是最大堆或最小堆).

数据结构--二叉堆与堆排序

二叉堆的概念 二叉堆,BinaryHeap,是二叉树中的常见的一种结构.通常以最大堆和最小堆的形式呈现.最大堆指的是父节点大于等于孩子节点的value值,也就是说对于最大堆而言,根元素是二叉堆最大的元素.最小堆的概念是与最大堆的概念是相似的.下图是最大堆的示意图: 二叉堆和排序之间的联系 二叉堆最显著的特征就是根元素是二叉树元素间最大的或者最小的.因此每次将二叉树最大或者最小的元素取出来,同时保证每次进行这样的操作后,剩下的元素依然可以保持二叉堆的性质,这样迭代这个过程,就可以完成排序的目的.

PHP利用二叉堆实现TopK-算法的方法详解

前言 在以往工作或者面试的时候常会碰到一个问题,如何实现海量TopN,就是在一个非常大的结果集里面快速找到最大的前10或前100个数,同时要保证 内存和速度的效率,我们可能第一个想法就是利用排序,然后截取前10或前100,而排序对于量不是特别大的时候没有任何问题,但只要量特别大是根本不可能 完成这个任务的,比如在一个数组或者文本文件里有几亿个数,这样是根本无法全部读入内存的,所以利用排序解决这个问题并不是最好的,所以我们这里就用 php去实现一个小顶堆来解决这个问题. 二叉堆 二叉堆是一种特殊的