数据结构与算法 ~ 图 ~ 图的遍历 ~ 深度优先搜索
/* graph ------adjacency List */
#include<stdlib.h>
#include<stdio.h>
#define MAX 20
/*弧结点信息*/
struct ArcNode{
int adjvex; /*该弧所指向的顶点的信息*/
struct ArcNode *nextarc; /*指向下一条弧的指针*/
};
struct VexNode{
int data;/*顶点信息*/
int flag;
struct ArcNode *firstarc;/*指向第一条依附于该顶点的弧的指针*/
};
struct VexNode head[MAX];/*顶点数组*/
int vexnum=-1;
int graphtype;
int formatlist(){
printf("\n1---创建无向图:");
printf("\n2---创建有向图:");
printf("\n0---退出");
printf("\n请输入你的选择:");
scanf("%d",&graphtype);
return graphtype;
}
void constr(struct VexNode *head,int source, int destination){
int max;
struct ArcNode *newNode,*pointer;
newNode=(struct ArcNode*)malloc(sizeof(struct ArcNode));/*分配空间*/
if (newNode==NULL){
printf("发生错误!");
exit(0);
}else{
newNode->adjvex=destination; /*生成弧结点*/
newNode->nextarc=NULL;
if ( head[source].firstarc==NULL) /*头结点没有邻接点*/
head[source].firstarc=newNode;
else{
pointer=head[source].firstarc ;/*头结点已有邻接点*/
while ((pointer->adjvex!=destination)&&(pointer->nextarc!=NULL) )
pointer=pointer->nextarc;/*找到最后一个邻接点*/
if (pointer->adjvex==destination){
printf("\n输入重复!");
free(newNode);
}else{
pointer->nextarc=newNode; /*接入*/
max=(source>destination)?source:destination; /*确定顶点的最大值*/
if (vexnum<max)
vexnum=max;
}/*else*/
}/*ifelse*/
}/*ifelse*/
}/*constr*/
void create_graph(struct VexNode *head){
int i,max,cost;
int source,destination;
struct ArcNode *newNode,*pointer;
for(i=1;i<MAX;++i){
head[i].data=i;
head[i].firstarc=NULL;
}
while(1){
printf("\n请输入弧的信息(起点 终点 退出输入-1):");
scanf("%d%d",&source,&destination,&cost);
if (source==-1)
break;
if (source==destination)
printf("\n输入重复!");
else{
constr(head,source,destination);
if (graphtype==1)
constr(head,destination,source);
}
}/*while*/
}/*create_graph*/
void Print(struct VexNode * head){
int i,j;
struct ArcNode *pointer;
printf("\n=====当前的图是=====\n");
for (i=1;i<=vexnum;++i){
printf( " head[%d]: ",i);
pointer=head[i].firstarc ;
while (pointer!=NULL){
printf("[%d]=>", pointer->adjvex);
pointer=pointer->nextarc;
}/*while*/
printf("\n");
}/*for*/
printf("\n===图的输出结束===\n");
}/*Print*/
int selectvex(){
int startvex;
printf("\n请输入遍历的起始结点(exit for -1):");
scanf("%d",&startvex);
return startvex;
}
void DFS(struct VexNode *head){
int stack[20];
int i,j,startvex,cur;
struct ArcNode *pointer;
printf("\n====深度优先搜索======\n");
startvex=selectvex();
while (startvex!=-1){
int top=0,base=0; /*top,base分别为栈的栈顶游标和栈底游标*/
for(i=0;i<=vexnum;++i)
head[i].flag=0; /*所有结点均设置为未访问*/
for(i=0;i<20;i++)
stack[i]=0; /*访问所用的栈初始化*/
/*输入数据合法性检验*/
if (startvex<0||startvex>vexnum){
printf("your input is error!");
exit(0);
}else {
stack[top++]=head[startvex].data;/*初始顶点进栈,栈顶游标上移*/
printf("[%d]==>",stack[top-1]);
head[startvex].flag=1; /*设置初始顶点已访问*/
/*栈不空*/
while(top!=base){
cur=stack[top-1];/*取栈顶元素*/
pointer=head[cur].firstarc; /*访问栈顶元素邻接表*/
while( pointer!=NULL&&head[pointer->adjvex].flag==1)
pointer=pointer->nextarc; /*取栈顶元素邻接表内未访问的弧结点*/
if (pointer==NULL)
top--;/*已访问其全部的邻接点或邻接点不存在,退栈*/
else if (head[pointer->adjvex].flag==0){
stack[top++]=pointer->adjvex; /*未访问的顶点入栈*/
printf("[%d]==>",stack[top-1]);
head[pointer->adjvex].flag=1;
}/*if*/
}/*while*/
}/*if_else*/
printf("\n====the DFS======\n");
startvex=selectvex();
}/*while*/
}/*DFS*/
int main(){
int answer,search;
answer=formatlist();
switch(answer){
case 1:
case 2: create_graph(head);break;
case 0: exit(0);
default:{
printf("\n你的输入错误,请重新输入\n");
answer=formatlist();}
}/*switch*/
Print(head);
DFS(head);
system("pause");
exit(0);
}
运行结果:
1---创建无向图:
2---创建有向图:
0---退出
请输入你的选择:1
请输入弧的信息(起点 终点 退出输入-1):1 2
请输入弧的信息(起点 终点 退出输入-1):1 3
请输入弧的信息(起点 终点 退出输入-1):2 4
请输入弧的信息(起点 终点 退出输入-1):2 5
请输入弧的信息(起点 终点 退出输入-1):4 8
请输入弧的信息(起点 终点 退出输入-1):5 8
请输入弧的信息(起点 终点 退出输入-1):3 6
请输入弧的信息(起点 终点 退出输入-1):3 7
请输入弧的信息(起点 终点 退出输入-1):6 7
请输入弧的信息(起点 终点 退出输入-1):-1 -1
=====当前的图是=====
head[1]: [2]=>[3]=>
head[2]: [1]=>[4]=>[5]=>
head[3]: [1]=>[6]=>[7]=>
head[4]: [2]=>[8]=>
head[5]: [2]=>[8]=>
head[6]: [3]=>[7]=>
head[7]: [3]=>[6]=>
head[8]: [4]=>[5]=>
===图的输出结束===
====深度优先搜索======
请输入遍历的起始结点(exit for -1):1
[1]==>[2]==>[4]==>[8]==>[5]==>[3]==>[6]==>[7]==>
====the DFS======
请输入遍历的起始结点(exit for -1):2
[2]==>[1]==>[3]==>[6]==>[7]==>[4]==>[8]==>[5]==>
====the DFS======
请输入遍历的起始结点(exit for -1):3
[3]==>[1]==>[2]==>[4]==>[8]==>[5]==>[6]==>[7]==>
====the DFS======
请输入遍历的起始结点(exit for -1):4
[4]==>[2]==>[1]==>[3]==>[6]==>[7]==>[5]==>[8]==>
====the DFS======
请输入遍历的起始结点(exit for -1):5
[5]==>[2]==>[1]==>[3]==>[6]==>[7]==>[4]==>[8]==>
====the DFS======
请输入遍历的起始结点(exit for -1):6
[6]==>[3]==>[1]==>[2]==>[4]==>[8]==>[5]==>[7]==>
====the DFS======
请输入遍历的起始结点(exit for -1):7
[7]==>[3]==>[1]==>[2]==>[4]==>[8]==>[5]==>[6]==>
====the DFS======
请输入遍历的起始结点(exit for -1):8
[8]==>[4]==>[2]==>[1]==>[3]==>[6]==>[7]==>[5]==>
====the DFS======
请输入遍历的起始结点(exit for -1):