Sie sind auf Seite 1von 6

/*

* About : C implementation of Dijkstra's algorithm


* Author : Ahmad F.
* Timestamp : 2009-OCT-29
* Version : 0.0
* Comments : requires graphfile.c
*/

#include<stdio.h>
#include<stdlib.h>
#include"graphfile.c"

void Heapify(int**,int,int);
void PopMinKey(int**,int);
void initSingleSource(int**,int*,int,int);
int findVertex(int**,int,int);
void printPath(int*,int);

int main()
{
int **graph;
int rows,cols;
int **distance;
int *predecessor;
int source;
int i,k,l;
int mindistant;

graph = readGraph("dijkstra.txt",&rows,&cols);

printGraph(graph,rows,cols);

distance = (int**)malloc(sizeof(int*)*(rows));

for(i=0;i<rows;i++)
{
distance[i] = (int*)malloc(2*sizeof(int));
}
predecessor = (int*)malloc(sizeof(int)*(rows));

/*user input for single source*/


printf("\nEnter source index [0 to %d]>>",rows-1);
scanf("%d",&source);

/*Init single source*/

initSingleSource(distance,predecessor,rows,source);

for(k=(rows-2)/2;k>=0;k--)
{
Heapify(distance,k,rows-1);
}

for(i=0;i<rows;i++)
{
/* A call to PopMinKey() will migrate
* the vertex with minimum distance
* towards the end of distance matrix
*/
PopMinKey(distance,rows-1-i);

mindistant = distance[rows-1-i][0];

for(k=0;k<rows;k++)
{
if(graph[mindistant][k] != 0) //if k is a neighbor of mindistant;
{

l = findVertex(distance,rows,k);

if( distance[l][1] > distance[rows-1-i][1] + graph[mindistant][l] )


{
distance[l][1] = distance[rows-1-i][1] + graph[mindistant][k];

predecessor[k] = mindistant;
}
}

}
}

for(i=0;i<rows;i++)
{
printf("\n");
printPath(predecessor,i);
printf("\t distance = %d",distance[findVertex(distance,rows,i)][1]);
}

printf("\n");

return 0;
}

void Heapify(int **heap,int start,int end)


{
int j = 2*start + 1; //begin with the left child of the start node
int pj;
int temp;

while (j<=end)
{
pj = (j-1)/2; //index of parent of j

/*
* find the index of the larger of the two siblings
*/

if(j<end)
{

if(heap[j][1] > heap[j+1][1])


{
j = j+1;
}
}

/*
* if parent is larger than or equal to
* the larger of its children
* break
*/
if(heap[pj][1] <= heap[j][1])
{
break;
}

/*
* else swap parent with larger child
* and set new child = left child of current child
*/

temp = heap[pj][1];
heap[pj][1] = heap[j][1];
heap[j][1] = temp;

temp = heap[pj][0];
heap[pj][0] = heap[j][0];
heap[j][0] = temp;

j = j * 2 + 1;

} //end of while

} //end of Heapify()

void PopMinKey(int **pque,int endptr)


{
int temp1,temp2;
static int deltaendptr = 1;
if(pque == NULL)
{
printf("\nEmpty queue");
exit(EXIT_SUCCESS);
}

/* No actual poppping of min element


* just move it to the last position
*/
temp1 = pque[0][0];
temp2 = pque[0][1];

pque[0][1] = pque[endptr][1];
pque[0][0] = pque[endptr][0];

pque[endptr][1] = temp2;
pque[endptr][0] = temp1;

/*
* We don't want to change the real end ptr
* so deltaendptr is required
*/

Heapify(pque,0,endptr-deltaendptr);

deltaendptr++;

} //end of PopMinKey()

void initSingleSource(int** d,int* pi,int end,int source)


{
int z;

for(z=0;z<end;z++)
{
d[z][0] = z;
d[z][1] = 65535;
pi[z] = -1;
}

d[source][1] = 0;
}

int findVertex(int** array,int end,int vertex)


{
int p;
for(p=0;p<end;p++)
{
if (array[p][0] == vertex)
{
return p;
}
}

return -1;
}

void printPath(int *predecessor,int vertex)


{
if(vertex == -1)
{
return;
}

printPath(predecessor,predecessor[vertex]);
printf(" %d ",vertex);
}

Das könnte Ihnen auch gefallen