堆的定义与操作

  如题,堆的定义与操作。

 1 #define MAXDATA 1000        /* 该值应根据具体情况定义为大于堆中所有可能元素的值 */
 2 
 3 typedef struct HNode *Heap; /* 堆的类型定义 */
 4 typedef int ElememntType;    /* 堆中的元素类型 */
 5 struct HNode {
 6     ElementType *Data;        /* 存储元素的数组 */
 7     int Size;                /* 堆中当前元素个数 */
 8     int Cap;                /* 堆的最大容量 */
 9 };    
10 typedef Heap MaxHeap;        /* 最大堆 */
11 typedef Heap MinHeap;         /* 最小堆 */
12 
13 /* 以最大堆为例 */
14 
15 MaxHeap CreateHeap(int MaxSize)
16 {
17     MaxHeap H = (MaxHeap)malloc(sizeof(struct HNode));
18     /* 堆中元素下标从 1 开始 */
19     H->Data = (ElementType*)malloc( (MaxSize+1) * sizeof(ElementType) );
20     H->Size = 0;
21     H->Cap = MaxSize;
22     H->Data[0] = MAXDATA;  /* 设置 "岗哨" ,大于 堆中所有可能元素的值 */
23     
24     return H;
25 } 
26 
27 int IsFull(MaxHeap H)
28 {
29     return ( H->Size == H->Cap );
30 }
31 
32 int IsEmpty(MaxHeap H) 
33 {
34     return ( H->Size == 0 );
35 }
36 
37 void Insert(MaxHeap H, ElementType X)
38 {    /* 将 X 插入到 堆 H 中,调整以符合最大堆的特性 */
39     /* 其中 H->Data[0] 已经定义为哨兵 */
40     int i;
41     if ( IsFull(H) ) return; // 堆已满 
42     
43     i = ++H->Size;
44     for ( ; H->Data[i/2] < X; i/=2 ) 
45         H->Data[i] = H->Data[i/2]; // 上滤 X 
46     H->Data[i] = X; // 将 X 插入 
47 }
48 
49 ElementType DeleteMax(MaxHeap H)
50 {/* 从最大堆H中取出键值最大的元素,并删除一个节点 */
51     int Parent, Child;
52     ElementType MaxItem, X;
53     
54     /* 这里省略判断堆是否已满的代码 */ 
55     
56     MaxItem = H->Data[1];     /* 取出根节点存放的最大值 */
57     /* 用 最大堆中最后一个元素从根节点开始向上过滤下层节点 */
58     X = H->Data[H->Size--]; /* 注意:当前堆的规模要减小 */
59     for ( Parent = 1; Parent*2 <= H->Size; Parent=Child ) {
60         Child = Parent * 2;
61         if ( (Child != H->Size) && (H->Data[Child] < H->Data[Child+1]) )
62             Child++; /* Chile 指向左右子节点的较大者 */
63         if ( X >= H->Data[Child]  ) break; /* 找到了合适位置 */ 
64         else /* 下滤X */ 
65             H->Data[Parent] = H->Data[Child];
66     }
67     H->Data[Parent] = X;
68     
69     return MaxItem; 
70 }
71 /* -------------建最大堆------------- */
72 void PercDown(MaxHeap H, int p) 
73 {/* 下滤:将 H 中以 H->Data[p] 为根的子堆调整为最大堆 */ 
74     int Parent, Child;
75     ElementType X;
76     
77     X = H->Data[p]; /* 取出根节点存放的值 */
78     for ( Parent = 1; Parent*2 <= H->Size; Parent=Child ) {
79         Child = Parent * 2;
80         if ( Child != H->Size && H->Data[Child] < H->Data[Child+1] )
81             Child++; /* Chile 指向左右子节点的较大者 */
82         if ( X >= H->Data[Child]  ) break; /* 找到了合适位置 */ 
83         else /* 下滤X */ 
84             H->Data[Parent] = H->Data[Child];
85     }
86     H->Data[Parent] = X;
87 } 
88 
89 void BuildHeap(MaxHeap H)
90 {/* 调整 H->Data[] 中的元素,使满足最大堆的有序性 */
91  /* 这里假设所有 H->Size 个元素已经存在 H->Data[] 中 */ 
92      
93     int i;
94     /* 从最后一个节点的父节点开始,到根节点 */
95     for ( i = (H->Size)/2; i > 0; i-- ) 
96         PercDown(H, i);
97 }

 

posted @ 2018-11-22 18:30  望汐  阅读(603)  评论(0编辑  收藏  举报