参考了书上的算法描述,写下来的prim,kruskal,AOV网络拓扑排序等的图相关的基础算法。做了一些注释
1.拓扑排序的如下:
#define MAX_VERTICES
struct node{
int vertex;
struct node *link;
};
typedef struct{
struct node *link;
int count;//入度
}hnode;//链表头结点
typedef struct node *node_pointer;
hnode graph[MAX_VERTICES];
void topsort(hnode graph[], int n)
{
node_pointer ptr;
int i;
int k;
int j;
int top = -1;
for(i=0; i<n; i++){
if(0 == graph[i].count){
graph[i].count = top;
top = i;
}
}
for(i=0; i<n; i++){
j = top;
top = graph[j].count;
printf("%d\n", j);
for(ptr = graph[j].link; ptr; ptr = ptr->link){
k = ptr->vertex;
graph[k].count --;
if(graph[k].count == 0){
graph[k].count = top;
top = k;
}
}
}
}
#include <stdio.h>
#include <string.h>
#define MAX_VERTECES 6
#define IN 10000
typedef int Graph[MAX_VERTECES][MAX_VERTECES];
int way[MAX_VERTECES];//记录路径中每个节点的父节点
void prim(Graph G, int vcount)
{
int i;
int k, j = 0;
int min = IN;
int m = 0;
int visited[MAX_VERTECES];
int cost[MAX_VERTECES];
int set[MAX_VERTECES];
for(i = 0; i < vcount; i++){
cost[i] = G[i][0];/*cost数组记录最短的边:当前最小生成树中德所有节点与其他节点最短的边的记录*/
set[i] = 0; /*set数组记录这个最短边的节点时哪一个*/
visited[i] = 0;
way[i] = -1;
}
visited[0] = 1;/*如果节点已经在目前的最小生成树了就把它置1,程序从0节点开始,所以先置1了*/
way[0] = 0;
/*一共需要vcount次添加边才能生成最小生成树 其中vcount是顶点的数量*/
for(i = 1; i < vcount; i++){
min = IN;
/*这个for循环找到当前可能的最小的边*/
for(k = 1; k < vcount; k++){
if(!visited[k] && (min > cost[k])){
min = cost[k];
j = k;
}
}
visited[j] = 1;
/*因为上一步新选中了节点,这一步就要更新cost数组中的值*/
for(k = 1; k < vcount; k++){
if(!visited[k] && (cost[k] > G[j][k])){
cost[k] = G[j][k];
set[k] = j;
}
}
way[i] = j;/*记录下所选中的节点,即为生成树的生成步骤*/
}
}
int main()
{
int i = 0;
Graph G = {
{IN,6,1,5,IN,IN},
{6,IN,5,IN,3,IN},
{1,5,IN,5,6,4},
{5,IN,5,IN,IN,2},
{IN,3,6,IN,IN,6},
{IN,IN,4,2,6,IN}
};
prim(G, 6);
printf("MST:");
for(; i < 6; i++)
printf("%d-->", way[i]);
return 0;
}