#include<stdio.h>
#include<stdlib.h>
#define MAXVEX 100 //最大顶点数
typedef char VertexType; //顶点
typedef int EdgeType; //权值
#define UNVISITED -1 //标记未访问
#define VISITED 1 //标记未访问
typedef struct
{
int from; //边的始点
int to; //边的终点
EdgeType weight; //权重
}Edge; //边的结构
typedef struct EdgeNode
{
int adjvex; //该顶点对应的下标
EdgeType weight; //权重
struct EdgeNode * next;
}EdgeNode;
typedef struct //顶点结构
{
VertexType data;
EdgeNode * firstedge;
}VertexNode,AdjList[MAXVEX];
typedef struct
{
AdjList adjList;
int numVertexes;
int numEdges;
int Indegree[MAXVEX];
int Mark[MAXVEX]; //标记是否被访问过
}GraphAdjList; //图结构
//初始化邻接表
void InitGraphAdjList(GraphAdjList * G,int numVer,int numEd) //传入顶点数和边数
{
G->numVertexes=numVer;
G->numEdges=numEd;
for(int i=0;i<G->numVertexes;i++)
{
G->Mark[i]=UNVISITED;
G->Indegree[i]=0;
G->adjList[i].firstedge=NULL; //将边表置空表
}
}
//创建一条边(无向图)
void UCreat_Edge(GraphAdjList * G,int from,int to,int weight)
{
EdgeNode * temp1 = G->adjList[from].firstedge;
EdgeNode * temp2 = G->adjList[to].firstedge;
if(temp1==NULL)
{
EdgeNode * NewEdgeNode1=(EdgeNode *)malloc(sizeof(EdgeNode));
NewEdgeNode1->adjvex=to;
NewEdgeNode1->weight=weight;
NewEdgeNode1->next=NULL;
G->adjList[from].firstedge=NewEdgeNode1;
G->Indegree[from]++;
}
else
{
while(temp1->next!=NULL)
{
temp1=temp1->next;
}
EdgeNode * NewEdgeNode1=(EdgeNode *)malloc(sizeof(EdgeNode));
NewEdgeNode1->adjvex=to;
NewEdgeNode1->weight=weight;
NewEdgeNode1->next=NULL;
temp1->next=NewEdgeNode1;
G->Indegree[from]++;
}
if(temp2==NULL)
{
EdgeNode * NewEdgeNode2=(EdgeNode *)malloc(sizeof(EdgeNode));
NewEdgeNode2->adjvex=from;
NewEdgeNode2->weight=weight;
NewEdgeNode2->next=NULL;
G->adjList[to].firstedge=NewEdgeNode2;
G->Indegree[to]++;
}
else
{
while(temp2->next!=NULL)
{
temp2=temp2->next;
}
EdgeNode * NewEdgeNode2=(EdgeNode *)malloc(sizeof(EdgeNode));
NewEdgeNode2->adjvex=from;
NewEdgeNode2->weight=weight;
NewEdgeNode2->next=NULL;
temp2->next=NewEdgeNode2;
G->Indegree[to]++;
}
}
//创建一条边(有向图)
void Creat_Edge(GraphAdjList * G,int from,int to,int weight)
{
EdgeNode * temp= G->adjList[from].firstedge;
if(temp==NULL)
{
EdgeNode * NewEdgeNode=(EdgeNode *)malloc(sizeof(EdgeNode));
NewEdgeNode->adjvex=to;
NewEdgeNode->weight=weight;
NewEdgeNode->next=NULL;
G->adjList[from].firstedge=NewEdgeNode;
G->Indegree[to]++;
}
else
{
while(temp->next!=NULL)
{
temp=temp->next;
}
EdgeNode * NewEdgeNode=(EdgeNode *)malloc(sizeof(EdgeNode));
NewEdgeNode->adjvex=to;
NewEdgeNode->weight=weight;
NewEdgeNode->next=NULL;
temp->next=NewEdgeNode;
G->Indegree[to]++;
}
}
/*建立图的邻接表结构(无向图)*/
void UGreateALGraph(GraphAdjList * G)
{
int i,j,k,w;
EdgeNode * e;
EdgeNode * a;
printf("请输入%d个元素:\n",G->numVertexes);
for(i=0;i<G->numVertexes;i++) /*读入顶点信息,建立顶点表*/
{
scanf(" %c",&G->adjList[i].data); /*输入顶点信息*/
G->adjList[i].firstedge=NULL; /*将边表置空表*/
}
for(k=0;k<G->numEdges;k++) /*建立边表*/
{
printf("输入边(Vi,Vj)上的顶点序号和权重:\n");
scanf("%d%d%d",&i,&j,&w); /*输入(Vi,Vj)上的顶点序号*/
UCreat_Edge(G,i,j,w);
}
}
/*建立图的邻接表结构(无向图)*/
void GreateALGraph(GraphAdjList * G)
{
int i,j,k,w;
EdgeNode * e;
EdgeNode * a;
printf("请输入%d个元素:\n",G->numVertexes);
for(i=0;i<G->numVertexes;i++) /*读入顶点信息,建立顶点表*/
{
scanf(" %c",&G->adjList[i].data); /*输入顶点信息*/
G->adjList[i].firstedge=NULL; /*将边表置空表*/
}
for(k=0;k<G->numEdges;k++) /*建立边表*/
{
printf("输入边(Vi,Vj)上的顶点序号和权重:\n");
scanf("%d%d%d",&i,&j,&w); /*输入(Vi,Vj)上的顶点序号*/
Creat_Edge(G,i,j,w);
}
}
Edge FirstEdge(GraphAdjList * G,int oneVertex)
{
Edge firstEdge;
firstEdge.from=oneVertex;
EdgeNode * temp=G->adjList[oneVertex].firstedge;
if(temp!=NULL)
{
firstEdge.to=temp->adjvex;
firstEdge.weight=temp->weight;
}
else
{
firstEdge.to=-1;
firstEdge.weight=-1;
}
return firstEdge;
}
//返回oneEdge的终点
int ToVertex(Edge oneEdge)
{
return oneEdge.to;
}
//返回与perEdge相同顶点的下一条边
Edge NextEdge(GraphAdjList * G,Edge perEdge)
{
Edge myEdge;
myEdge.from=perEdge.from;
EdgeNode * temp=G->adjList[perEdge.from].firstedge;
while(temp!=NULL && temp->adjvex<=perEdge.to)
{
temp=temp->next;
}
if(temp!=NULL)
{
myEdge.to=temp->adjvex;
myEdge.weight=temp->weight;
}
else
{
myEdge.to=-1;
myEdge.weight=-1;
}
return myEdge;
}
//判断是否为边
bool IsEdge(Edge oneEdge)
{
if(oneEdge.to==-1)
{
return false;
}
else
{
return true;
}
}
//访问当前的顶点
void Vist(GraphAdjList * G,int v)
{
printf("%c ",G->adjList[v]);
}
//图的深度优先周游(DFS)算法
void DFS(GraphAdjList * G,int v)
{
G->Mark[v]=VISITED;
Vist(G,v);
for(Edge e=FirstEdge(G,v);IsEdge(e);e=NextEdge(G,e))
{
if(G->Mark[ToVertex(e)]==UNVISITED)
{
DFS(G,ToVertex(e));
}
}
}
int main()
{
GraphAdjList G;
int numVer,numEd;
int start;
int choose;
printf("请输入顶点元素个数和边数:\n");
scanf("%d%d",&numVer,&numEd);
InitGraphAdjList(&G,numVer,numEd);
printf("请选择:\n1.无向图\n2.有向图\n");
scanf("%d",&choose);
if(choose==1)
{
UGreateALGraph(&G);
}
else if(choose==2)
{
GreateALGraph(&G);
}
else
{
printf("选择错误!\n");
return 0;
}
printf("请选择以哪个顶点作为起始点遍历,请输入其下标:\n");
scanf("%d",&start);
DFS(&G,start);
printf("\n");
return 0;
}