图论——Dijkstra+prim算法涉及到的优先队列(二叉堆)
2015-11-19 09:40
766 查看
【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); else printf("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); else printf("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 1 void 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 } else break; } *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 } else i = ++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:
相关文章推荐
- Lua教程(七):数据结构详解
- 解析从源码分析常见的基于Array的数据结构动态扩容机制的详解
- C#数据结构揭秘一
- 数据结构之Treap详解
- JavaScript数据结构和算法之图和图算法
- Java数据结构及算法实例:冒泡排序 Bubble Sort
- Java数据结构及算法实例:插入排序 Insertion Sort
- Java数据结构及算法实例:考拉兹猜想 Collatz Conjecture
- java数据结构之java实现栈
- java数据结构之实现双向链表的示例
- Java数据结构及算法实例:选择排序 Selection Sort
- Java数据结构及算法实例:朴素字符匹配 Brute Force
- Java数据结构及算法实例:汉诺塔问题 Hanoi
- Java数据结构及算法实例:快速计算二进制数中1的个数(Fast Bit Counting)
- java数据结构和算法学习之汉诺塔示例
- Java数据结构及算法实例:三角数字
- Java数据结构之简单链表的定义与实现方法示例
- 数据结构之AVL树详解
- qqwry.dat的数据结构图文解释第1/2页
- JavaScript中数据结构与算法(五):经典KMP算法