赞
踩
- 16 //初始化,决定是大堆还是小堆
- 17 void HeapInit(Heap* heap,Compare cmp)
- 18 {
- 19 if(heap == NULL)
- 20 {
- 21 //非法输入
- 22 return ;
- 23 }
- 24 heap->size = 0;
- 25 heap ->cmp = cmp;
- 26 return ;
- 27 }
- 5 //为大堆打造的比较函数
- 6 int Greater(HeapType a,HeapType b)
- 7 {
- 8 return a>b?1:0;
- 9 }
- 10
- 11 //为小堆打造的比较函数
- 12 int Less(HeapType a,HeapType b)
- 13 {
- 14 return a<b?1:0;
- 15 }
- 29 //销毁堆
- 30 //注:此时内存不能释放,因为没有malloc
- 31 void HeapDestroy(Heap* heap)
- 32 {
- 33 if(heap == NULL)
- 34 {
- 35 //非法输入
- 36 return ;
- 37 }
- 38 heap->size = 0;
- 39 heap->cmp = NULL;
- 40 return ;
- 41 }
72 void HeapInsert(Heap* heap ,HeapType value) 73 { 74 if(heap == NULL) 75 { 76 //非法输入 77 return ; 78 } 79 //相当于对数组进行尾插 80 if(heap->size >= HeapMaxSize) 81 { 82 //堆满 83 return ; 84 } 85 heap->data[heap->size++] = value; 86 //对这个堆进行上浮式调整 87 //调整的起始位置为size-1,即插入的元素 88 AdjustUp(heap,heap->size-1); 89 return ; 90 }
51 void AdjustUp(Heap* heap,size_t index) 52 { 53 //index表示从哪个位置开始调整 54 size_t child = index; 55 size_t parent = (child - 1)/2; 56 while(child > 0) 57 { 58 if(!heap->cmp(heap->data[parent],heap->data[child])) 59 { 60 Swap(&heap->data[parent],&heap->data[child]); 61 } 62 else 63 { 64 //若发现某个位置下的child,parent已满足堆的要求,就停止上浮 65 //因为上面的节点已经满足堆的要求 66 break; 67 } 68 child = parent; 69 parent = (child - 1)/2; 70 } 71 }
- 45 void Swap(HeapType* a,HeapType* b)
- 46 {
- 47 HeapType tmp = *a;
- 48 *a = *b;
- 49 *b = tmp;
- 50 }
4.取堆顶元素
相当于取数组的第一个元素
92 //取堆顶元素 93 int HeapRoot(Heap* heap,HeapType* value) 94 { 95 if(heap == NULL) 96 { 97 //非法输入 98 return 0; 99 } 100 if(heap->size == 0) 101 { 102 //空堆 103 return 0; 104 } 105 *value = heap->data[0]; 106 return 1; 107 }
下面为AdjustDown函数将堆首元素进行“下沉”
136 void HeapErase(Heap* heap) 137 { 138 if(heap == NULL) 139 { 140 //非法输入 141 return ; 142 } 143 if(heap->size == 0) 144 { 145 //空堆 146 return ; 147 } 148 //交换堆顶与最后一个元素 149 Swap(&heap->data[0],&heap->data[heap->size-1]); 150 //--size进行尾删 151 --heap->size; 152 //从根节点出发进行下沉 153 AdjustDown(heap,0); 154 return ; 155 }
109 //删除堆顶元素 110 void AdjustDown(Heap* heap,size_t index) 111 { 112 size_t parent = index; 113 size_t child = 2*index+1;//左子树 114 while(child < heap->size) 115 { 116 //child+1表示右子树 117 if(child+1 < heap->size && heap->cmp(heap->data[child+1],heap->data[child])) 118 { 119 //若右子树存在,且右子树比左子树更符合堆的要求 120 //假设为小堆:右子树<做子树,且让child指向右子树 121 child = child+1; 122 } 123 //child指向左右子树中更小的那个元素 124 if(heap->cmp(heap->data[child],heap->data[parent])) 125 { 126 Swap(&heap->data[child],&heap->data[parent]); 127 } 128 else 129 { 130 break; 131 } 132 parent = child; 133 child = 2*parent+1; 134 }
157 //给一个数组,将数组构建成堆,这个堆通过heap来表示 158 //时间复杂度为O(N*logN) 159 void HeapCreate(Heap* heap,HeapType arry[],size_t size) 160 { 161 if(heap == NULL) 162 { 163 return ; 164 } 165 //遍历arry数组,将数组元素依次插入到堆中 166 size_t i = 0; 167 for(;i<size;++i) 168 { 169 HeapInsert(heap,arry[i]); 170 } 171 return; 172 } 173
174 //实现堆排序 175 //升序->大堆 176 //降序->小堆 177 void HeapSort(HeapType arry[],size_t size) 178 { 179 //把数组构建成堆 180 Heap heap; 181 HeapInit(&heap,Greater); 182 HeapCreate(&heap,arry,size); 183 //循环将堆进行删除操作 184 while(heap,size>0) 185 { 186 HeapErase(&heap); 187 } 188 //循环结束后,堆排序完成了 189 memcpy(arry,heap.data,size* sizeof(HeapType)); 190 return ; 191 }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。