| 网站首页 | 业界新闻 | 小组 | 威客 | 人才 | 下载频道 | 博客 | 代码贴 | 在线编程 | 编程论坛
欢迎加入我们,一同切磋技术
用户名:   
 
密 码:  
共有 4927 人关注过本帖, 1 人收藏
标题:[原创]有向图转换&遍历&拓扑&最短路径
只看楼主 加入收藏
haroldi
Rank: 1
等 级:新手上路
帖 子:158
专家分:0
注 册:2006-7-22
收藏(1)
 问题点数:0 回复次数:3 
[原创]有向图转换&遍历&拓扑&最短路径

#include <stdio.h>
#include <stdlib.h>
#include <limits.h>
#define MaxStr 20
typedef int Status;
typedef int ElemType;
typedef struct{
ElemType VNode;
int indgree;
}VexType;
typedef struct Arc{
VexType Adj;
unsigned int Weight;
struct Arc *NextArc;
}ArcType;
typedef struct{
VexType *Vex;
ArcType **FirstArc; //邻接表;
// ArcType **InvertArc; //逆邻接表;
int VexNums; //顶点总数;
}DLGraph; //图的邻接表结构定义;
typedef struct{
ElemType *Vex;
unsigned int **Arc;
int VexNums;
}DMGraph; //图的邻接矩阵结构定义;
//========================================================================================
Status CreateDMGraph(DMGraph *DMG); //创建图的邻接矩阵;
Status DMG_Traver(DMGraph DMG); //邻接矩阵的遍历;
Status DMG_DFS(DMGraph DMG,int v,int *Visited); //邻接矩阵深度遍历(递 归);
Status DMG_DFS_Uni(DMGraph DMG,int v,int *Visited); //邻接矩阵深度遍历(非递归);
Status DMG_BFS(DMGraph DMG,int v,int *Visited); //邻接矩阵广度遍历;
Status DMG2DLG(DMGraph DMG,DLGraph *DLG); //邻接矩阵转换为邻接表;
Status DLG_Traver(DLGraph DLG); //邻 接 表的遍历;
Status DLG_DFS(DLGraph DLG,int v,int *Visited); //邻 接 表深度遍历(递 归);
Status DLG_DFS_Uni(DLGraph DLG,int v,int *Visited); //邻 接 表深度遍历(非递归);
Status DLG_BFS(DLGraph DLG,int v,int *Visited); //邻 接 表广度遍历;
//---------------------------------------------------------
Status Topsort(DLGraph DLG,ElemType **ts); //邻接表有向图的Topsort;
Status Dijkstra(DMGraph DMG,ElemType v,unsigned int *dist);//Dijkstra;
Status PRN_DK(DMGraph DMG,unsigned int ***dis); //输出Dijkstra算法;
Status Floyd(DMGraph DMG,unsigned int ***flyd); //Floyd;
Status PRN_DMGraph(DMGraph DMG); //输出邻接矩阵;
Status PRN_DLGraph(DLGraph DLG); //输出邻接表;
//========================================================================================
int main(void)
{
int i,j;
DMGraph DMG;
DLGraph DLG;
ElemType *ts;
unsigned int **dist,**flyd;
printf( " 一、创立有向图的邻接矩阵:\n");
CreateDMGraph(&DMG);
PRN_DMGraph(DMG);
printf("\n\n 二、有向图-邻接矩阵的遍历:\n");
DMG_Traver(DMG);
printf("\n\n 三、邻接矩阵转换为邻接表:\n");
DMG2DLG(DMG,&DLG);
PRN_DLGraph(DLG);
printf("\n\n 四、有向图-邻接表的遍历:\n");
DLG_Traver(DLG);
printf("\n\n 五、邻接表有向图的拓扑排序:\n");
Topsort(DLG,&ts);
printf("\n\n\n");system("pause");
printf("\n\n 六、邻接矩阵有向图的各点最短路径:\n\n 1. Dijkstra(迪杰斯特拉算法):");
PRN_DK(DMG,&dist);
printf("\n\n\n 2. Floyd(弗洛伊德算法):");
Floyd(DMG,&flyd);

printf("\n"); system("pause");
printf("\n\n\nDijkstra最短路径测试输出:\n 某两点 : 最短路径");
for(i = 1;i <= DMG.VexNums;i++)
for(j = 1;j <= DMG.VexNums;j++)
if(dist[i][j] < INT_MAX) printf("\n[%2d,%2d] : %5d ",i,j,dist[i][j]);
printf("\n\nFloyd最短路径测试输出:\n 某两点 : 最短路径");
for(i = 1;i <= DMG.VexNums;i++)
for(j = 1;j <= DMG.VexNums;j++)
if(flyd[i][j] < INT_MAX) printf("\n[%2d,%2d] : %5d ",i,j,flyd[i][j]);
printf("\n"); system("pause");
return 0;
}

// 文件格式参见"无向图"说明:
//http://bbs.bc-cn.net/viewthread.php?tid=129767

[此贴子已经被作者于2007-4-21 21:30:55编辑过]

搜索更多相关主题的帖子: 有向图 遍历 拓扑 路径 typedef 
2007-04-11 11:23
haroldi
Rank: 1
等 级:新手上路
帖 子:158
专家分:0
注 册:2006-7-22
收藏
得分:0 
回复:(haroldi)有向图转换&遍历&拓扑&最短路径

Status CreateDMGraph(DMGraph *DMG) //创建图的邻接矩阵;
{
char ReadFileName[MaxStr];
unsigned int w;
FILE *fp;
int i,j;
do{
printf("\n 输入文本文件名:");
gets(ReadFileName);
}while(ReadFileName[0] == '\0' || !(fp = fopen(ReadFileName,"r")));

fscanf(fp,"%d",&DMG->VexNums); //得到顶点总数;
if(!(DMG->Vex = (ElemType *)malloc((DMG->VexNums+1)*sizeof(ElemType))))
{printf("\n内存溢出。");return 1;}
if(!(DMG->Arc = (unsigned int **)malloc((DMG->VexNums+1)*sizeof(unsigned int*))))
{printf("\n内存溢出。");return 1;}
for(i = 1;i <= DMG->VexNums;i++) //邻接矩阵初始化;
{
DMG->Vex[i] = i; //
if(!(DMG->Arc[i]=(unsigned int *)malloc((DMG->VexNums+1)*sizeof(unsigned int))))
{printf("\n内存溢出。");return 1;}
for(j = 1;j <= DMG->VexNums;j++)
{
DMG->Arc[i][j] = INT_MAX;
}
}
while(fscanf(fp,"%d%d%u",&i,&j,&w) == 3) DMG->Arc[i][j] = w;//
fclose(fp);
return 0;
}
//========================================================================================
Status DMG2DLG(DMGraph DMG,DLGraph *DLG) //图的邻接矩阵转换为邻接表;
{
int i,j;
ArcType *p = NULL;
DLG->VexNums = DMG.VexNums;
if(!(DLG->Vex = (VexType *)malloc((DLG->VexNums+1)*sizeof(VexType))))
{printf("\n内存溢出。");return 1;}
if(!(DLG->FirstArc = (ArcType **)malloc((DLG->VexNums+1)*sizeof(ArcType*))))
{printf("\n内存溢出。");return 1;}
for(i = 1;i <= DLG->VexNums;i++)
{
DLG->Vex[i].VNode = DMG.Vex[i]; //
DLG->FirstArc[i] = NULL;
DLG->Vex[i].indgree = 0;
for(j = 1;j <= DMG.VexNums;j++)
{
if(DMG.Arc[i][j] < INT_MAX)
{
if(!(p = (ArcType *)malloc(sizeof(ArcType))))
{printf("\n内存溢出。");return 1;}
p->Adj.VNode = DMG.Vex[j];
p->Weight = DMG.Arc[i][j];
p->NextArc = DLG->FirstArc[i];
DLG->FirstArc[i] = p;
}
}
for(j = 1;j <= DMG.VexNums;j++)
{
if(DMG.Arc[j][i] < INT_MAX) ++DLG->Vex[i].indgree;
}
}
return 0;
}
//========================================================================================
Status DMG_Traver(DMGraph DMG) //邻接矩阵的遍历;
{
int i,*Visited;
if(!(Visited = (int *)malloc((DMG.VexNums+1)*sizeof(int))))
{printf("\n内存溢出。");return 1;}
printf("\n 1. 图的深度遍历:\n递 归:");
for(i = 1;i <= DMG.VexNums;i++) Visited[i] = 0;
for(i = 1;i <= DMG.VexNums;i++)
if(Visited[i] == 0) DMG_DFS(DMG,i,Visited);
printf("\n非递归:");
for(i = 1;i <= DMG.VexNums;i++) Visited[i] = 0;
for(i = 1;i <= DMG.VexNums;i++)
if(Visited[i] == 0) DMG_DFS_Uni(DMG,i,Visited);
printf("\n\n 2. 图的广度遍历:\n\t");
for(i = 1;i <= DMG.VexNums;i++) Visited[i] = 0;
for(i = 1;i <= DMG.VexNums;i++)
if(Visited[i] == 0) DMG_BFS(DMG,i,Visited);
return 0;
}
//========================================================================================
Status DLG_Traver(DLGraph DLG) //邻 接 表的遍历;
{
int i,*Visited;
if(!(Visited = (int *)malloc((DLG.VexNums+1)*sizeof(int))))
{printf("\n内存溢出。");return 1;}
printf("\n 1. 图的深度遍历:\n递 归:");
for(i = 1;i <= DLG.VexNums;i++) Visited[i] = 0;
for(i = 1;i <= DLG.VexNums;i++)
if(Visited[i] == 0) DLG_DFS(DLG,i,Visited);
printf("\n非递归:");
for(i = 1;i <= DLG.VexNums;i++) Visited[i] = 0;
for(i = 1;i <= DLG.VexNums;i++)
if(Visited[i] == 0) DLG_DFS_Uni(DLG,i,Visited);
printf("\n\n 2. 图的广度遍历:\n\t");
for(i = 1;i <= DLG.VexNums;i++) Visited[i] = 0;
for(i = 1;i <= DLG.VexNums;i++)
if(Visited[i] == 0) DLG_BFS(DLG,i,Visited);
printf("\n");
return 0;
}
//========================================================================================
Status DMG_DFS(DMGraph DMG,int v,int *Visited) //邻接矩阵深度遍历(递 归);
{
int i;
Visited[v] = 1;
printf("%2d ->",v);
for(i = 1;i <= DMG.VexNums;i++)
if(Visited[i] == 0 && DMG.Arc[v][i] < INT_MAX)
DMG_DFS(DMG,i,Visited);
return 0;
}
//========================================================================================
Status DLG_DFS(DLGraph DLG,int v,int *Visited) //邻 接 表深度遍历(递 归);
{
ArcType *p = NULL;
Visited[v] = 1;
printf("%2d ->",v);
p = DLG.FirstArc[v];
while(p != NULL)
{
if(Visited[p->Adj.VNode] == 0) DLG_DFS(DLG,p->Adj.VNode,Visited);
p = p->NextArc;
}
return 0;
}
//========================================================================================
Status DMG_DFS_Uni(DMGraph DMG,int v,int *Visited) //邻接矩阵深度遍历(非递归);
{
int i,*Stack,top = -1;
if(!(Stack = (int *)malloc((DMG.VexNums+1)*sizeof(int))))
{printf("\n内存溢出。");return 1;}
Visited[v] = 1;
printf("%2d ->",v);
Stack[++top] = v;
while(top != -1)
{
for(i = 1;i <= DMG.VexNums;i++)
if(Visited[i] == 0 && DMG.Arc[Stack[top]][i] < INT_MAX)
{
Visited[i] = 1;
printf("%2d ->",i);
Stack[++top] = i;
break;
}
if(i == DMG.VexNums+1) --top;
}
return 0;
}
//========================================================================================
Status DLG_DFS_Uni(DLGraph DLG,int v,int *Visited) //邻 接 表深度遍历(非递归);
{
int *Stack,top = -1;
ArcType *p = NULL;
if(!(Stack = (int *)malloc((DLG.VexNums+1)*sizeof(int))))
{printf("\n内存溢出。");return 1;}
Visited[v] = 1;
printf("%2d ->",v);
Stack[++top] = v;
while(top != -1)
{
p = DLG.FirstArc[Stack[top]];
while(p != NULL)
{
if(Visited[p->Adj.VNode] == 0)
{
Visited[p->Adj.VNode] = 1;
printf("%2d ->",p->Adj.VNode);
Stack[++top] = p->Adj.VNode;
break;
}
p = p->NextArc;
}
if(p == NULL) --top;
}
return 0;
}
//========================================================================================
Status DMG_BFS(DMGraph DMG,int v,int *Visited) //邻接矩阵广度遍历;
{
int i,*Queue,rear,front;
if(!(Queue = (int *)malloc((DMG.VexNums+1)*sizeof(int))))
{printf("\n内存溢出。");return 1;}
Visited[v] = 1;
printf("%2d ->",v);
rear = front = 0;
rear = (rear+1)%DMG.VexNums;
Queue[rear] = v;
while(rear != front)
{
front = (front+1)%DMG.VexNums;
for(i = 1;i <= DMG.VexNums;i++)
if(Visited[i] == 0 && DMG.Arc[Queue[front]][i] < INT_MAX)
{
Visited[i] = 1;
printf("%2d ->",i);
rear = (rear+1)%DMG.VexNums;
Queue[rear] = i;
}
}
return 0;
}
//========================================================================================
Status DLG_BFS(DLGraph DLG,int v,int *Visited) //邻 接 表广度遍历;
{
ArcType *p = NULL;
int *Queue,rear,front;
if(!(Queue = (int *)malloc((DLG.VexNums+1)*sizeof(int))))
{printf("\n内存溢出。");return 1;}
rear = front = 0;
Visited[v] = 1;
printf("%2d ->",v);
rear = (rear+1)%DLG.VexNums;
Queue[rear] = v;
while(rear != front)
{
front = (front+1)%DLG.VexNums;
p = DLG.FirstArc[Queue[front]];
while(p != NULL)
{
if(Visited[p->Adj.VNode] == 0)
{
Visited[p->Adj.VNode] = 1;
printf("%2d ->",p->Adj);
rear = (rear+1)%DLG.VexNums;
Queue[rear] = p->Adj.VNode;
}
p = p->NextArc;
}
}
return 0;
}
//========================================================================================
Status Topsort(DLGraph DLG,ElemType **ts) //邻接表有向图的Topsort拓扑排序;
{
int i,j,k,m = 0,top = -1;
ArcType *tp,*p;
if(!(*ts = (ElemType *)malloc((DLG.VexNums+1)*sizeof(ElemType))))
{printf("\n内存溢出。");return 1;}
if(!(tp = (ArcType *)malloc((DLG.VexNums+1)*sizeof(ArcType))))
{printf("\n内存溢出。");return 1;}
printf(" Topsort:\n\n ");
for(i = 1;i <= DLG.VexNums;i++) //初始化tp;
{
tp[i].Adj.VNode = DLG.Vex[i].VNode;
tp[i].NextArc = DLG.FirstArc[i];
tp[i].Adj.indgree = DLG.Vex[i].indgree;
if(DLG.Vex[i].indgree == 0)
{
tp[i].Adj.indgree = top;
top = i;
}
}
while(top != -1)
{
j = top;
top = tp[top].Adj.indgree;
printf(" %2d ,",tp[j].Adj.VNode);
++m;
p = tp[j].NextArc;
while(p != NULL)
{
k = p->Adj.VNode;
--tp[k].Adj.indgree;
if(tp[k].Adj.indgree == 0)
{
tp[k].Adj.indgree = top;
top = k;
}
p = p->NextArc;
}
}
if(m < DLG.VexNums) printf("\n不能拓扑!\n");
return 0;
}
//========================================================================================
Status PRN_DK(DMGraph DMG,unsigned int ***dis) //输出Dijkstra最短路径;
{
int i,j,flag;
unsigned int **dist;
if(!(dist = (unsigned int **)malloc((DMG.VexNums+1)*sizeof(unsigned int*))))
{printf("\n内存溢出。");return 1;}
*dis = dist;
for(i = 1;i <= DMG.VexNums;i++)
{
if(!(dist[i] = (unsigned int *)malloc((DMG.VexNums+1)*sizeof(unsigned int))))
{printf("\n内存溢出。");return 1;}
Dijkstra(DMG,i,dist[i]); //Dijkstra最短路径;
}
for(i = 1;i <= DMG.VexNums;i++)
{
flag = 0;
printf("\n从%3d出发的最短路径:",i);
for(j = 1;j <= DMG.VexNums;j++)
{
if(j != i && dist[i][j] < INT_MAX)
{
printf("\n\t自%3d ==>%3d点:%4d",i,j,dist[i][j]);
flag = 1;
//if(j != i && dist[i][j] == INT_MAX) printf("\n\t自%3d ==>%3d点: ∞",i,j);
//else if(j == i);printf("\n\t自%3d ==>%3d点:%4d",i,j,dist[i][j]);
}
}
if(flag == 0) printf("\n\t没有任何路径...555555");
}
return 0;
}
//========================================================================================
Status Dijkstra(DMGraph DMG,ElemType v,unsigned int *dist)//最短路径Dijkstra(迪杰斯特拉);
{
int i,j,t;
ElemType *flag;
unsigned int min;
if(!(flag = (ElemType *)malloc((DMG.VexNums+1)*sizeof(ElemType))))
{printf("\n内存溢出。");return 1;}
for(i = 1;i <= DMG.VexNums;i++) //初始化,置U={v}到V-U到各点最短路径;
{
flag[i] = 0;
dist[i] = DMG.Arc[v][i];
}
flag[v] = 1; //v并入U;
for(i = 1;i <= DMG.VexNums;i++)
{
min = INT_MAX;
t = i;
for(j = 1;j <= DMG.VexNums;j++) //找到U到V-U最小权值(最短路径);
{
if(flag[j] == 0 && min > dist[j])
{
min = dist[j];
t = j;
}
}
flag[t] = 1; //t并入U;
for(j = 1;j <= DMG.VexNums;j++) //重置U到V-U各点最短路径;
{
if(flag[j] == 0 && dist[t] + DMG.Arc[t][j] < dist[j])
{
dist[j] = dist[t] + DMG.Arc[t][j];
}
}
}
return 0;
}
//========================================================================================
Status Floyd(DMGraph DMG,unsigned int ***flyd) //Floyd(弗洛伊德)最短路径;
{ int i,j,k,**Path = NULL;
unsigned int **Weight = NULL;
if(!(Path = (int **)malloc((DMG.VexNums+1)*sizeof(int*))))
{printf("\n内存溢出。");return 1;}
if(!(Weight = (unsigned int **)malloc((DMG.VexNums+1)*sizeof(unsigned int*))))
{printf("\n内存溢出。");return 1;}
*flyd = Weight;
for(i = 1;i <= DMG.VexNums;i++) //初始化;
{
if(!(Path[i] = (int *)malloc((DMG.VexNums+1)*sizeof(int))))
{printf("\n内存溢出。");return 1;}
if(!(Weight[i] = (unsigned int *)malloc((DMG.VexNums+1)*sizeof(unsigned int))))
{printf("\n内存溢出。");return 1;}
for(j = 1;j <= DMG.VexNums;j++)
{
Weight[i][j] = DMG.Arc[i][j];
Path[i][j] = 0;
}
}
for(k = 1;k <= DMG.VexNums;k++) //Floyd迭代算法;
for(i = 1;i <= DMG.VexNums;i++)
for(j = 1;j <= DMG.VexNums;j++)
if(Weight[i][j] > (Weight[i][k] + Weight[k][j]))
{
Weight[i][j] = Weight[i][k] + Weight[k][j];
Path[i][j] = k;
}
for(i = 1;i <= DMG.VexNums;i++) //输出;
{
printf("\n从%3d出发的最短路径:",i);
for(j = 1;j <= DMG.VexNums;j++)
{
if(j != i && Weight[i][j] < INT_MAX)
printf("\n\t自%3d ==>%3d点:%4d",i,j,Weight[i][j]);
}
}
return 0;
}
//========================================================================================
Status PRN_DMGraph(DMGraph DMG) //输出邻接矩阵;
{
int i,j;
for(i = 1;i <= DMG.VexNums;i++)
{
printf("\n\t");
for(j = 1;j <= DMG.VexNums;j++)
{
if(DMG.Arc[i][j] < INT_MAX) printf(" %3d ",DMG.Arc[i][j]);
else printf(" ∞ ");
}
printf("\n");
}
return 0;
}
//========================================================================================
Status PRN_DLGraph(DLGraph DLG) //输出邻接表;
{
int i;
ArcType *p = NULL;
for(i = 1;i <= DLG.VexNums;i++)
{
printf("\n %2d(入度%2d) ==> ",i,DLG.Vex[i].indgree);
p = DLG.FirstArc[i];
while(p != NULL)
{
if(p->NextArc) printf("%2d(%3d) ->",p->Adj.VNode,p->Weight);
else printf("%2d(%3d) 。",p->Adj.VNode,p->Weight);
p = p->NextArc;
}
}
return 0;
}


Do people want thick road ...
2007-04-11 11:24
快速回复:[原创]有向图转换&遍历&拓扑&最短路径
数据加载中...
 
   



关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.052676 second(s), 7 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved