图的代码实现及操作:
#include <malloc.h>
#define MAX_VERTEX_NUM 20
#define INF 32767 //无穷大
#define OK 1
#define ERROR 0
#define OVERFLOW -2
#define FALSE 0
#define TRUE 1

typedef enum ...{DG,DN,UDG,UDN} GraphKind;
typedef int VertexType;
typedef struct 
...{
VertexType vexs[MAX_VERTEX_NUM+1];
int arcs[MAX_VERTEX_NUM+1][MAX_VERTEX_NUM+1];
int Vexnum;
GraphKind kind;
}MGraph; //邻接矩阵的存储结构
typedef struct ArcNode
...{
int adjvex;
struct ArcNode *nextarc;
}ArcNode;
typedef struct VNode
...{
int data;
ArcNode *firstarc;
}VNode;
typedef struct
...{
VNode vertices[MAX_VERTEX_NUM+1];
int vexnum,arcnum;
GraphKind kind;
}ALGraph;//邻接表的存储结构

typedef struct dge
...{
int adjvex;
int lowcost;
}dge,closedge[MAX_VERTEX_NUM+1];
int visited[MAX_VERTEX_NUM+1];
//创建邻接矩阵
void Create(MGraph* g,GraphKind kind)
...{
int i,j;
printf("input vertexs numbers: ");
scanf("%d",&g->Vexnum);
for(i =1;i<=g->Vexnum;i++)
...{
printf(" vertex No. %d",i);
scanf("%d",&g->vexs[i]);
}
for( i=1;i<=MAX_VERTEX_NUM;i++)
for(j=1;j<=MAX_VERTEX_NUM;j++)
g->arcs[i][j]=0;
printf(" input edges:");
scanf("%d%d",&i,&j);
while((i!=0)&&(j!=0))
...{
g->arcs[i][j]=1;
if(kind==UDG)
g->arcs[j][i]=1;
printf(" input edges:");
scanf("%d%d",&i,&j);
}
}
/**//*由数组生成邻接矩阵*/
void CreateByArray(MGraph *G,GraphKind kind,int *array,int dim)
...{
int i;
G->kind=kind;
G->Vexnum=dim;
for(i=1;i<=dim;i++)
...{
G->vexs[i]=i;
}
for(i=1;i<=dim;i++)
for(int j=1;j<=dim;j++)
...{
G->arcs[i][j]=*array++;
}
}
/**//*生成图*/
void CreateGraph(MGraph *G)
...{
printf("input graph kind: 0.有向图 1,有向图 2.无向图 3.无向网 ");
scanf("%d",&G->kind);
switch(G->kind)
...{
case DG:
Create(G,DG);
break;
case UDG:
Create(G,UDG);
break;
}
}

/**//*由邻接矩阵生成邻接表*/
void CreateALGraphByMGraph(ALGraph *G,MGraph M)
...{
int i,flag;
ArcNode *p;
G->vexnum=M.Vexnum;
G->kind=M.kind;
for(i=1;i<=M.Vexnum;i++)
...{
G->vertices[i].data=M.vexs[i];
G->vertices[i].firstarc=NULL;
}
for(i=1;i<=M.Vexnum;i++)
...{
flag=0;
for(int j=1;j<=M.Vexnum;j++)
...{
if(M.arcs[i][j]!=0&&flag==0)
...{
p=(ArcNode *)malloc(sizeof(ArcNode));
p->adjvex=j;
p->nextarc=NULL;
G->vertices[i].firstarc=p;
flag=1;
}
else if(M.arcs[i][j]!=0&&flag==1)
...{
p->nextarc=(ArcNode *)malloc(sizeof(ArcNode));
p=p->nextarc;
p->adjvex=j;
p->nextarc=NULL;
}
}/**//*
for(int j=1;j<=M.Vexnum;j++)
{
if(M.arcs[i][j])
{
p=(ArcNode *)malloc(sizeof(ArcNode));
p->adjvex=j;
p->nextarc=G->vertices[i].firstarc;
G->vertices[i].firstarc=p;
}
}*/
}
}
/**//*遍历邻接表*/
void TraverseALGraph(ALGraph G)
...{
for(int i=1;i<=G.vexnum;i++)
...{
ArcNode *p=G.vertices[i].firstarc;
printf("%d ",G.vertices[i].data);
while(p)
...{
printf("%d ",p->adjvex);
p=p->nextarc;
}
printf(" ");
}
}
/**//*v的第一个邻接点*/
int FirstAdjVex(MGraph *g,int v)
...{
int i;
for(i=1;i<g->Vexnum;i++)
if(g->arcs[v][i]>0&&g->arcs[v][i]<INF)
return i;
return 0;
}
/**//*w的邻接点*/
int NextAdjVex(MGraph *g,int v,int w)
...{
int i=0;
for(i=w+1;i<g->Vexnum;i++)
if(g->arcs[v][i]>0&&g->arcs[v][i]<INF)
return i;
return 0;
}
void DFS(MGraph *g,int v)
...{
int w=0;
visited[v]=1;
printf("%d ",g->vexs[v]);
for(w=FirstAdjVex(g,v);w;w=NextAdjVex(g,v,w))
...{
if(!visited[w])
DFS(g,w);
}
}
/**//*深度优先遍历*/
void DFSTraverse(MGraph *g)
...{
int i;
for(i=1;i<=g->Vexnum;i++)
visited[i]=0;
for(i=1;i<=g->Vexnum;i++)
if(!visited[i])
DFS(g,i);
} 
/**//*邻接表的深度优先遍历*/
void DFS2(ALGraph *g,int visited[],int v)
...{
struct ArcNode *p;
visited[v]=1;
printf("%d, ",g->vertices[v].data);
p=g->vertices[v].firstarc;
while(p)
...{
if(!visited[p->adjvex])
DFS2(g,visited,p->adjvex);
p=p->nextarc;
}
}
/**//*邻接表的深度优先遍历*/
void DFSTraverse2(ALGraph *g,int v)
...{
int visited[MAX_VERTEX_NUM+1];
for(int i=1;i<=g->vexnum;i++)
visited[i]=0;
DFS2(g,visited,v);
}

/**//*深度优先遍历(非递归)*/
void Adj_NonDFS(ALGraph *g,int v)
...{
int visited[MAX_VERTEX_NUM+1],i,j;
int stack[MAX_VERTEX_NUM+1],top=-1;
struct ArcNode *p;
for(i=1;i<=g->vexnum;i++)
visited[i]=FALSE;
stack[++top]=v;
while(top>-1)
...{
j=stack[top--];
printf("%d, ",g->vertices[j].data);
visited[j]=TRUE;
p=g->vertices[j].firstarc;
while(p)
...{
if(!visited[p->adjvex])
stack[++top]=p->adjvex;
p=p->nextarc;
}
}
}
//广度优先遍历
void BSFTraverse(MGraph *g)
...{
int Q[MAX_VERTEX_NUM];
int front=0,rear=0;
int u;
for(int i=1;i<=g->Vexnum;i++)
...{
visited[i]=FALSE;
}
for(int v=1;v<=g->Vexnum;v++)
...{
if(!visited[v])
...{
visited[v]=TRUE;
printf("%d, ",g->vexs[v]);
Q[rear++]=v;
while(rear!=front)
...{
u=Q[front];
front=(front+1)%MAX_VERTEX_NUM;
for(int w=FirstAdjVex(g,u);w;w=NextAdjVex(g,u,w))
...{
if(!visited[w])
...{
visited[w]=TRUE;
printf("%d, ",g->vexs[w]);
if((rear+1)%MAX_VERTEX_NUM==front)
...{
printf("队列已满!");
return;
}
Q[rear]=w;
rear=(rear+1)%MAX_VERTEX_NUM;
}
}
}
}
}
}
/**//*求有向图的入度*/
int ITD(MGraph *G,int col)
...{
int s=0;
if(G->kind!=DG)
...{
printf("Not a DG!");
return 0;
}
for(int i=1;i<=G->Vexnum;i++)
...{
s+=G->arcs[i][col];
}
return s;
}
//求有向图各顶点的度
void FindInDegree(MGraph *G,int *degree)
...{
for(int i=1;i<=G->Vexnum;i++)
degree[i]=ITD(G,i);
}
//拓扑排序
int TopologicalSort(ALGraph *G,int *degree)
...{
int stack[MAX_VERTEX_NUM],top=-1,i,count=0;
ArcNode *p;
int k;
for(i=1;i<=G->vexnum;i++)
if(!degree[i])
stack[++top]=i;
while(top>-1)
...{
i=stack[top--];
printf(" num %d verx %d ",i,G->vertices[i].data);
count++;
for(p=G->vertices[i].firstarc;p;p=p->nextarc)
...{
k=p->adjvex;
if(!(--degree[k]))
stack[++top]=k;
}
}
if(count<G->vexnum)
return ERROR;
else
return OK;
}
//求最小的边
int minimumver(closedge e)
...{
int min=INF;
int closever;
for(int i=1;i<=MAX_VERTEX_NUM;i++)
...{
if(e[i].lowcost>0&&e[i].lowcost<min)
...{
min=e[i].lowcost;
closever=i;
}
}
return closever;
}
/**//*Prim 算法*/
void MiniSpanTree_PRIM(MGraph *G,int v)
...{
closedge cdge;
int k;
for(int j=1;j<=G->Vexnum;j++)
...{
if(j!=v)
...{
cdge[j].adjvex=v;
cdge[j].lowcost=G->arcs[v][j];
}
}//辅助数组初始化
cdge[v].lowcost=0;
for(int i=1;i<G->Vexnum;i++)
...{
k=minimumver(cdge);
printf(" from %d to %d: %d ",cdge[k].adjvex,G->vexs[k],G->arcs[cdge[k].adjvex][k]);
cdge[k].lowcost=0;
for(int j=1;j<=G->Vexnum;j++)
...{
if(G->arcs[k][j]<cdge[j].lowcost)
...{
cdge[j].adjvex=G->vexs[k];
cdge[j].lowcost=G->arcs[k][j];
}
}
}
}
int main(int agrc,char* argv[])
...{
MGraph G1;
ALGraph G2;
int degree[9];
// CreateGraph(&G1);
int array[4][4]=...{...{0,1,1,0},...{0,0,0,0},...{0,0,0,1},...{1,0,0,0}};
// int array[6][6]={{0,1,1,1,0,0},{0,0,0,0,0,0},{0,1,0,0,1,0},{0,0,0,0,1,0},{0,0,0,0,0,0},{0,0,0,1,1,0}};
// int array[6][6]={{INF,6,1,5,INF,INF},{6,INF,5,INF,3,INF},{1,5,INF,5,6,4},{5,INF,5,INF,INF,2},{INF,3,6,INF,INF,6},{INF,INF,4,2,6,INF}};
// int array[6][6]={{0,6,1,5,0,0},{6,0,5,0,3,0},{1,5,0,5,6,4},{5,0,5,0,0,2},{0,3,6,0,0,6},{0,0,4,2,6,0}};
// int array[8][8]={{0,1,1,0,0,0,0,0},{1,0,0,1,1,0,0,0},{1,0,0,0,0,1,1,0},{0,1,0,0,0,0,0,1},{0,1,0,0,0,0,0,1},{0,0,1,0,0,0,1,0},{0,0,1,0,0,1,0,0},{0,0,0,1,1,0,0,0}};
CreateByArray(&G1,DG,*array,4);
printf("deep first traverse: ");
DFSTraverse(&G1);
printf(" broad traverse: ");
BSFTraverse(&G1);
FindInDegree(&G1,degree);
// MiniSpanTree_PRIM(&G1,1);
CreateALGraphByMGraph(&G2,G1);
printf(" topo sort: ");
TopologicalSort(&G2,degree);
// CreateALGraphByMGraph(&G2,G1);
printf(" traverse adj: ");
// TraverseALGraph(G2);
Adj_NonDFS(&G2,1);
printf(" deep traverse adj: ");
DFSTraverse2(&G2,1);
}
本文介绍了图的基本存储结构——邻接矩阵与邻接表,并实现了图的各种基本操作,包括创建、遍历(深度优先与广度优先)等。此外还展示了如何利用邻接矩阵生成邻接表,以及如何进行拓扑排序。
579

被折叠的 条评论
为什么被折叠?



