zoukankan      html  css  js  c++  java
  • 图论——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("
     error: %s 
    ",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("
     error: %s 
    ",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("
    	 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("
    ");	
    }  
    
    //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("
    	 index[%d] = ", i);
    		if(i < bh->size)
    			printf("%d", bh->elements[i]->distance);
    		else
    			printf("NULL");
    	}
    	printf("
    ");
    }  
    
    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("	indexOfVertexInHeap[%d] = %d
    ", 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("
    	=== test for inserting the binary heap with {85, 80, 40, 30, 10, 70, 110} in turn ===
    ");
    	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("
    	=== test for inserting the binary heap with element {100, 20, 90} in turn ===
    ");
    	
    	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("
    	=== test for inserting the binary heap with 5 ===
    ");	
    	tempDisStruct->distance = 5;
    	tempDisStruct->vertexIndex = size+3;
    	insert(tempDisStruct, bh, indexOfVertexInHeap);	
    	printBinaryHeap(bh);
    
    	printf("
    	=== test for 3 deletings towards the minimum in binary heap ===
    ");
    	deleteMin(bh, indexOfVertexInHeap);	
    	printBinaryHeap(bh);
    	deleteMin(bh, indexOfVertexInHeap);		
    	printBinaryHeap(bh);
    	deleteMin(bh, indexOfVertexInHeap);	
    	printBinaryHeap(bh);
    }
    
    
    

    3.3)printing results:
    这里写图片描述
    这里写图片描述
    这里写图片描述

  • 相关阅读:
    Network in Network
    cord-in-a-box 2.0 安装指南
    L2 约束的最小二乘学习法
    点估计
    递归简介
    向量的L2范数求导
    优雅的线性代数系列三
    ansible批量部署nginx
    ansible批量部署mysql
    ansible批量部署tomcat
  • 原文地址:https://www.cnblogs.com/pacoson/p/4976629.html
Copyright © 2011-2022 走看看