图论——Dijkstra+prim算法涉及到的优先队列(二叉堆)
【0】README
0.1)為什么有這篇文章?因為 Dijkstra算法的優先隊列實現 涉及到了一種新的數據結構,即優先隊列(二叉堆)的操作需要更改以適應這種新的數據結構,我們暫且吧它定義為Distance, 而不是單純的int類型;
0.2)本文源代碼均為原創, int類型的優先隊列(二叉堆)的操作實現,參見http://blog.csdn.net/PacosonSWJTU/article/details/49498255, (并比較他們的打印結果,很有必要)
【1】因為 Dijkstra算法的優先隊列實現, 需要用到二叉堆的相關操作,但是操作的元素類型(ElementType 不是 單純的int類型), 而是如下:
struct Distance {int vertexIndex; //當前頂點下標int distance; //初始頂點到當前頂點的distance };【2】看個荔枝
2.1)需要特別說明的是: indexOfVertexInHeap 數組記錄的是頂點vertex在 heap中的位置, 如 indexOfVertexInHeap [1] = 4;表明heap的第4個位置記錄這 編號為1的vertex;
2.2)優先隊列的insert和deleteMin 的執行演示(請將我的手動演示結果同我的代碼打印結果做對比,經過對比,你發現它們的效果是一致的,恰好說明了我的代碼的可行性):
Attention)
- A1)其實本文中的二叉堆優先隊列的實現源代碼和 int類型的優先隊列源代碼類似,只不過它們操作的數據類型不一樣罷了,當然, 這只需要簡單的修改即可;
- A2)打印結果在文末,可以看到,ElementType采用int 和 Distance的打印效果一樣,這正證明了我們采用Distance結構體對源碼的修改是無誤的,相比于單純的int 類型,只不過Distance又多了一個 頂點下標vertexIndex成員變量而已;
【3】source code + printing results
3.1)download source code:
https://github.com/pacosonTang/dataStructure-algorithmAnalysis/tree/master/chapter9/binaryHeap_dijkstra_prim
3.2)source code at a glance:(for complete code , please click the given link above)
1st file:distance.h
#include <stdio.h>#define Error(str) printf("\n error: %s \n",str) struct Distance; typedef struct Distance *Distance; struct Distance {int vertexIndex;int distance; };Distance makeEmptyDistance();2nd file:distance.c
#include "distance.h" #include <malloc.h>// allocate the memory for Distance struct Distance makeEmptyDistance() {Distance element;element = (Distance)malloc(sizeof(struct Distance));if(!element){Error("out of space ,from func makeEmptyDistance");return NULL;} return element; }3rd file:binaryheap.h
#include <stdio.h> #include <malloc.h> #include "distance.h"#define ElementType Distance#define Error(str) printf("\n error: %s \n",str) struct BinaryHeap; typedef struct BinaryHeap *BinaryHeap;void swap(ElementType x, ElementType y); BinaryHeap initBinaryHeap(int capacity); void insert(ElementType value, BinaryHeap bh, int*); ElementType deleteMin(BinaryHeap, int*); int isFull(BinaryHeap bh); int isEmpty(BinaryHeap bh); void percolateUp(int index, BinaryHeap bh); void percolateDownFromOne(int index, BinaryHeap bh, int*); void printBinaryHeap(BinaryHeap bh); void printBinaryHeapFromZero(BinaryHeap bh);struct BinaryHeap {int capacity;int size; ElementType *elements; };4th file:binaryheap.c
#include "binaryheap.h" #include <math.h>#define MaxInt (int)pow(2, 16) //judge whether the BinaryHeap is full or not , also 1 or 0 int isFull(BinaryHeap bh) {return bh->size == bh->capacity - 1; }//judge whether the BinaryHeap is empty or not , also 1 or 0 int isEmpty(BinaryHeap bh) {return bh->size == 0; }// get the left child of node under index with startup 1 int leftChildFromOne(int index) {return index * 2; }void printBinaryHeap(BinaryHeap bh) {int i;ElementType *temp;if(!bh)Error("printing execution failure, for binary heap is null, from func printBinaryHeap"); temp = bh->elements;for(i = 1; i < bh->capacity; i++){printf("\n\t heap[%d] = ", i);if(i <= bh->size)printf("vertex[%d] + distance[%d]", bh->elements[i]->vertexIndex+1, bh->elements[i]->distance); elseprintf("NULL");}printf("\n"); } //print the binary heap who starts from index 0 void printBinaryHeapFromZero(BinaryHeap bh) {int i;ElementType *temp;if(!bh)Error("printing execution failure, for binary heap is null, from func printBinaryHeap"); temp = bh->elements;for(i = 0; i < bh->capacity; i++){printf("\n\t index[%d] = ", i);if(i < bh->size)printf("%d", bh->elements[i]->distance);elseprintf("NULL");}printf("\n"); } void swap(ElementType x, ElementType y) {struct Distance temp;temp = *x;*x = *y;*y = temp; }ElementType deleteMin(BinaryHeap bh, int* heapIndexRecord) { ElementType minimum;ElementType *data; if(isEmpty(bh)){Error("failed deleting minimum , for the BinaryHeap is empty, from func deleteMin !");return NULL; }data = bh->elements; minimum = data[1];swap(data[1], data[bh->size]); bh->size-- ; // size-- occurs prior to percolateDownFromOne percolateDownFromOne(1, bh, heapIndexRecord) ; return minimum; } // percolating down the element when its value is greater than children (minimal heap)//Attention: all of bh->elements starts from index 1void percolateDownFromOne(int index, BinaryHeap bh, int* heapIndexRecord){ ElementType *data;int size;struct Distance temp;int child;data = bh->elements;size = bh->size; for(temp = *data[index]; leftChildFromOne(index) <= size; index = child){child = leftChildFromOne(index);if(child < size && data[child]->distance > data[child+1]->distance)child++;if(temp.distance > data[child]->distance){ *data[index] = *data[child]; heapIndexRecord[bh->elements[index]->vertexIndex] = index; //update the heapIndexRecord}elsebreak;} *data[index] = temp; heapIndexRecord[bh->elements[index]->vertexIndex] = index; //update the heapIndexRecord}// Attention, the index of the heap starts from 1 // return the index the element inserted into the binary heap void insert(ElementType value, BinaryHeap bh, int* heapIndexRecord) {int i;if(isFull(bh)){Error("failed insertion , for the BinaryHeap is full, from func insert!");return ; } if(!isEmpty(bh))for(i = ++bh->size; bh->elements[i/2]->distance > value->distance; i /= 2) {//copyElement(bh->elements[i/2], bh->elements[i]); *bh->elements[i] = *bh->elements[i/2];heapIndexRecord[bh->elements[i]->vertexIndex] = i; //update the heapIndexRecord}elsei = ++bh->size; *bh->elements[i] = *value;heapIndexRecord[bh->elements[i]->vertexIndex] = i; //update the heapIndexRecord }BinaryHeap initBinaryHeap(int capacity) {BinaryHeap bh;ElementType *temp;int i;bh = (BinaryHeap)malloc(sizeof(struct BinaryHeap));if(!bh) {Error("out of space, from func initBinaryHeap"); return NULL;} bh->capacity = capacity;bh->size = 0;temp = (ElementType*)malloc(capacity * sizeof(Distance));if(!temp) {Error("out of space, from func initBinaryHeap"); return NULL;} bh->elements = temp;for(i=0; i < capacity; i++){temp[i] = (ElementType)malloc(sizeof(struct Distance));if(!temp[i]) {Error("out of space, from func initBinaryHeap"); return NULL;} }return bh; }// allocate the memory for storing index of vertex in heap and let every element -1 int *makeEmptyArray(int size) {int *array;int i;array = (int*)malloc(size * sizeof(int));if(!array){Error("out of space ,from func makeEmptyArray");return NULL;} for(i=0; i<size; i++)array[i] = -1;return array; } void printIndexOfVertexInHeap(int size, int *array) {int i;for(i=0; i<size; i++) printf("\tindexOfVertexInHeap[%d] = %d\n", i+1, array[i]); }int main() {int data[] = {85, 80, 40, 30, 10, 70, 110}; // P141 int buildHeapData[] = {150, 80, 40, 30, 10, 70, 110, 100, 20, 90, 60, 50, 120, 140, 130};BinaryHeap bh; int size;int i; int capacity;Distance tempDisStruct;int *indexOfVertexInHeap;printf("\n\t=== test for inserting the binary heap with {85, 80, 40, 30, 10, 70, 110} in turn ===\n");capacity = 14;bh = initBinaryHeap(capacity);size = 7; tempDisStruct = makeEmptyDistance(); indexOfVertexInHeap = makeEmptyArray(size);for(i = 0; i < size; i++) {tempDisStruct->distance = data[i];tempDisStruct->vertexIndex = i;insert(tempDisStruct, bh, indexOfVertexInHeap);} printBinaryHeap(bh);printIndexOfVertexInHeap(bh->size, indexOfVertexInHeap);printf("\n\t=== test for inserting the binary heap with element {100, 20, 90} in turn ===\n");tempDisStruct->distance = 100;tempDisStruct->vertexIndex = size;insert(tempDisStruct, bh, indexOfVertexInHeap); printBinaryHeap(bh);tempDisStruct->distance = 20;tempDisStruct->vertexIndex = size+1;insert(tempDisStruct, bh, indexOfVertexInHeap); printBinaryHeap(bh);tempDisStruct->distance = 90;tempDisStruct->vertexIndex = size+2;insert(tempDisStruct, bh, indexOfVertexInHeap); printBinaryHeap(bh);printIndexOfVertexInHeap(bh->size, indexOfVertexInHeap);printf("\n\t=== test for inserting the binary heap with 5 ===\n"); tempDisStruct->distance = 5;tempDisStruct->vertexIndex = size+3;insert(tempDisStruct, bh, indexOfVertexInHeap); printBinaryHeap(bh);printf("\n\t=== test for 3 deletings towards the minimum in binary heap ===\n");deleteMin(bh, indexOfVertexInHeap); printBinaryHeap(bh);deleteMin(bh, indexOfVertexInHeap); printBinaryHeap(bh);deleteMin(bh, indexOfVertexInHeap); printBinaryHeap(bh); }3.3)printing results:
總結
以上是生活随笔為你收集整理的图论——Dijkstra+prim算法涉及到的优先队列(二叉堆)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 接口与回调
- 下一篇: 手机怎么设置iis(手机怎么设置无线路由