[开源]有向图和无向图的基本操作(VC)
运行环境:VC
//有向图,无向图基本操作,包括:
1、邻接矩阵
2、邻接表
3、深度优先遍历
4、广度优先遍历
5、最小生成树
6、拓扑排序
7、每一对顶点之间的最短路径(Dijkstra,Floyd两种算法)
有疑问的地方可以发邮件或MSN:longfeng867@163.com.
#include <stdio.h>
#include <stdlib.h>
#include <conio.h>
#include <limits.h>
#define MaxStr 20
#define inf 999
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 ;
//顶点总数;
int VexNums ;
//边数
int ArcNums ;
}
DLGraph ;
//图的邻接表结构定义;
typedef struct
{
ElemType*Vex ;
int kind ;
unsigned int**Arc ;
int VexNums ;
int ArcNums ;
}
DMGraph ;
//图的邻接矩阵结构定义;
//========================================================================================
Status Create(DMGraph*DMG);
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);
//输出邻接表;
//========================================================================================
/*最小生成树*/
Status Prim(DMGraph*g)
{
int closest[MaxStr],i,j,k,min ;
unsigned int lowcost[MaxStr];
//VexNums个顶点,VexNums-1条边
for(i=2;i<=g->VexNums;i++)
{
lowcost[i]=g->Arc[1][i];
//初始化
closest[i]=1 ;
//顶点未加入到最小生成树
}
lowcost[1]=0 ;
//标志顶点1加入U集合
//形成VexNums-1条边的生成
for(i=2;i<=g->VexNums;i++)
{
min=inf ;
k=0 ;
//寻找满足边的一个顶点在U,另一个顶点在V的最小边
for(j=2;j<=g->VexNums;j++)if((lowcost[j]<min)&&(lowcost[j]!=0))
{
min=lowcost[j];
k=j ;
}
printf("(%d,%d)%d\t",closest[k],k,min);
lowcost[k]=0 ;
//顶点k加入U
//修改由顶点k到其他顶点边的路径
for(j=2;j<=g->VexNums;j++)if(g->Arc[k][j]<lowcost[j])
{
lowcost[j]=g->Arc[k][j];
closest[j]=k ;
}
printf("\n");
}
return 0 ;
}
//========================================================================================
void Menu(DMGraph DMG,DLGraph DLG)
{
char c ;
int i,j ;
unsigned int**dist,**flyd ;
ElemType*ts ;
for(;;)
{
printf("\t ╭──────────────────────╮\n");
printf("\t | 图的基本操作实现 |\n");
printf("\t |──────────────────────|\n");
printf("\t | 1__邻接矩阵 |\n");
printf("\t |──────────────────────|\n");
printf("\t | 2__邻接表 |\n");
printf("\t |──────────────────────|\n");
printf("\t | 3__深度优先搜索 |\n");
printf("\t |──────────────────────|\n");
printf("\t | 4__广度优先搜索 |\n");
printf("\t |──────────────────────|\n");
printf("\t | 5__最小生成树 |\n");
printf("\t |──────────────────────|\n");
printf("\t | 6__拓扑排序 |\n");
printf("\t |──────────────────────|\n");
printf("\t | 7__每一对顶点之间的最短路径 |\n");
printf("\t |──────────────────────|\n");
printf("\t | 8__返回重新操作... |\n");
printf("\t |──────────────────────|\n");
printf("\t | Q__退出程序... |\n");
printf("\t ╰──────────────────────╯\n");
printf("\t 请选择图的实现:\t");
scanf("%s",&c);
switch(c)
{
case '1' :
system("cls");
printf(" 图的邻接矩阵:\n");
PRN_DMGraph(DMG);
system("pause");
system("cls");
break ;
case '2' :
system("cls");
printf("\n\n 邻接矩阵转换为邻接表:\n");
DMG2DLG(DMG,&DLG);
PRN_DLGraph(DLG);
printf("\n");
system("pause");
system("cls");
break ;
case '3' :
system("cls");
DMG_Traver(DMG);
printf("\n");
system("pause");
system("cls");
break ;
case '4' :
system("cls");
DLG_Traver(DLG);
printf("#");
printf("\n");
system("pause");
system("cls");
break ;
case '5' :
system("cls");
if(DMG.kind==2)
Prim(&DMG);
if(DMG.kind==1)
printf("\n\n\n\n\t\t\t Error: 不能最小生成数树!!!\n");
system("pause");
system("cls");
break ;
case '6' :
system("cls");
printf("\n\n 图的拓扑排序:\n");
Topsort(DLG,&ts);
printf("\n\n\n");
system("pause");
system("cls");
break ;
case '7' :
system("cls");
printf("\n 图的各点最短路径:\n\n 1. Dijkstra(迪杰斯特拉算法):\n");
PRN_DK(DMG,&dist);
printf("\n\n");
system("pause");
system("cls");
printf(" 2. Floyd(弗洛伊德算法):\n");
Floyd(DMG,&flyd);
printf("\n\n");
system("pause");
system("cls");
printf("\nDijkstra最短路径测试输出:\n 某两点 : 最短路径");
for(i=1;i<=DMG.VexNums;i++)
for(j=1;j<=DMG.VexNums;j++)
if(dist[i][j]<INT_MAX&&j!=i)
printf("\n[%2d,%2d] : %5d ",i,j,dist[i][j]);
printf("\n\n");
system("pause");
system("cls");
printf("\nFloyd最短路径测试输出:\n 某两点 : 最短路径");
for(i=1;i<=DMG.VexNums;i++)
for(j=1;j<=DMG.VexNums;j++)
if(flyd[i][j]<INT_MAX&&j!=i)
printf("\n[%2d,%2d] : %5d ",i,j,flyd[i][j]);
printf("\n\n");
system("pause");
system("cls");
break ;
case '8' :
system("cls");
Create(&DMG);
system("cls");
break ;
case 'Q' :
case 'q' :
system("cls");
printf("\n\n\n\n\t\t\t 谢 谢 使 用!!!\n");
printf("\t\t\t");
exit(0);
break ;
default :
printf("输入有错,请重试!!!\n");
getch();
system("cls");
break ;
}
}
}
DMGraph DMG ;
DLGraph DLG ;
int main(void)
{
Create(&DMG);
system("cls");
Menu(DMG,DLG);
return 0 ;
}
//========================================================================================
//创建无向图
Status CreateDMGraph1(DMGraph*g)
{
int i,j,k,l,v1,v2,w ;
printf("\n请输入要创建的顶点数:");
scanf("%d",&g->VexNums);
printf("\n请输入要创建的边数:");
scanf("%d",&g->ArcNums);
if(!(g->Vex=(ElemType*)malloc((g->VexNums+1)*sizeof(ElemType))))
{
printf("\n内存溢出。");
return 1 ;
}
if(!(g->Arc=(unsigned int**)malloc((g->VexNums+1)*sizeof(unsigned int*))))
{
printf("\n内存溢出。");
return 1 ;
}
printf("无向图的接点的代号为:");
for(i=1;i<=g->VexNums;i++)
{
g->Vex[i]=i ;
if(!(g->Arc[i]=(unsigned int*)malloc((g->VexNums+1)*sizeof(unsigned int))))
{
printf("\n内存溢出。");
return 1 ;
}
for(j=1;j<=g->VexNums;j++)
{
g->Arc[i][j]=INT_MAX ;
}
printf("%d ",g->Vex[i]);
}
printf("\n");
for(j=1;j<=g->VexNums;j++)
for(k=1;k<=g->VexNums;k++)
g->Arc[j][k]=inf ;
//邻接矩阵初始化
for(l=1;l<=g->ArcNums;l++)
{
loop1 :
;
printf("\n输入第%d条边的起点v1(1-%d):",l,g->VexNums);
scanf("%d",&v1);
if(v1<0||v1>g->VexNums)
{
printf("\t\t\tError: 超出范围,重新输入!!!\n");
goto loop1 ;
}
loop :
;
printf("\n输入第%d条边的终点v2(1-%d):",l,g->VexNums);
scanf("%d",&v2);
if(v2<0||v2>g->VexNums||v1==v2)
{
printf("\t\t\tError: 超出范围或输入不合法,重新输入!!!\n");
goto loop ;
}
printf("\n输入第%d条边的路径w(编号为数字):",l);
scanf("%d",&w);
g->Arc[v1][v2]=w ;
g->Arc[v2][v1]=w ;
}
return 0 ;
}
//==========================================================================
//创建图的邻接矩阵;
Status CreateDMGraph(DMGraph*DMG)
{
int i,j,k,w ;
printf("请输入有向图的顶点数目:");
scanf("%d",&DMG->VexNums);
printf("\n请输入要创建的边数:");
scanf("%d",&DMG->ArcNums);
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 ;
}
//邻接矩阵初始化;
printf("有向图的接点代号为:");
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 ;
}
printf("%d ",DMG->Vex[i]);
}
printf("\n");
for(i=1;i<=DMG->ArcNums;i++)
{
loop1 :
;
printf("请输入第%d组边的起点(1-%d):",i,DMG->VexNums);
scanf("%d",&k);
if(k<0||k>DMG->VexNums)
{
printf("\t\t\tError: 超出范围,重新输入!!!\n");
goto loop1 ;
}
loop :
;
printf("请输入第%d组边的终点(1-%d):",i,DMG->VexNums);
scanf("%d",&j);
if(j<0||j>DMG->VexNums||j==k)
{
printf("\t\t\tError: 超出范围或输入不合法,重新输入!!!\n");
goto loop ;
}
printf("请输入第%d组边的路径:",i);
scanf("%d",&w);
DMG->Arc[k][j]=w ;
}
return 0 ;
}
//====================================================================
//创建图的邻接矩阵;
Status Create(DMGraph*DMG)
{
char c ;
loop :
;
printf("\n\n\n");
printf("\t ╭─────────────────────╮\n");
printf("\t | 图的基本操作实现 |\n");
printf("\t |─────────────────────|\n");
printf("\t | 1、有向图 |\n");
printf("\t |─────────────────────|\n");
printf("\t | 2、无向图 |\n");
printf("\t |─────────────────────|\n");
printf("\t | 3、退 出 |\n");
printf("\t ╰─────────────────────╯\n");
printf("\t 请选择:");
scanf("%s",&c);
if(c=='2')
{
DMG->kind=2 ;
system("cls");
CreateDMGraph1(DMG);
system("cls");
}
else if(c=='1')
{
DMG->kind=1 ;
system("cls");
CreateDMGraph(DMG);
system("cls");
}
else if(c=='3')
{
system("cls");
printf("\n\n\n\n\t\t\t 谢 谢 使 用!!!\n");
printf("\t\t\t");
exit(0);
}
else
{
printf("\t\t Error: 输入错误,请重新选择!!!\n");
getch();
system("cls");
goto loop ;
}
return 0 ;
}
//========================================================================================
[此贴子已经被作者于2007-10-10 10:44:39编辑过]