#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#define MAX_VERTEX_NUM 20
#define OVERFLOW 0
#define OK 1
#define TRUE 1
#define FALSE 0
typedef int Status ;
typedef char VertexType;
typedef int QElemType;
typedef struct ArcNode
{
int adjvex; //邻接点域,存储该邻点顶点对应的下标
struct ArcNode *nextarc; //邻节点
int weight; //权值
}ArcNode;
/*邻接表结构*/
typedef struct VNode
{
VertexType data; //顶点对应的值
ArcNode *firstarc; //边表头指针指向邻顶点
}VNode,AdjList[MAX_VERTEX_NUM];
typedef struct
{
AdjList vertices;
int vexnum,arcnum; //顶点数,边数
}ALGraph;
/*队列结构*/
typedef struct QNode
{
QElemType data;
struct QNode *next;
}QNode,*QueuePtr;
//typedef struct
//{
// QueuePtr front; //队头指针
// QueuePtr rear; //队尾指针
//}LinkQueue;
//
//Status InitQueue(LinkQueue Q)//构造一个空队列
//{
// Q.front = Q.rear = (QueuePtr)malloc(sizeof(QNode));//队头结点
// if(!Q.front)
// exit(OVERFLOW);
// Q.front ->next = NULL;
// return OK;
//}
//
//Status QueueEmpty(const LinkQueue &Q)//若队列为空,则返回TRUE,否则返回FALSE
//{
// if(Q.rear == Q.front)
// return TRUE;
// return FALSE;
//}
//
//Status EnQueue(LinkQueue &Q, QElemType e) //插入元素e为Q的新队尾元素
//{
// QueuePtr p = (QueuePtr)malloc(sizeof(QNode));
// if(!p)
// exit(OVERFLOW);
// p->data = e;
// p->next = NULL;
// Q.rear->next = p;
// Q.rear = p;
// return OK;
//}
//Status DeQueue(LinkQueue &Q,QElemType &e) //若队列不空,则删除Q的队头元素,用e返回其值,并返回OK;
//{
// if(Q.front == Q.rear)
// {
// return FALSE; //队空
// }
// QueuePtr p = Q.front->next;
// e = p->data; //一定要申明,否则遍广度历出队时找不到对应的值
// Q.front->next = p->next;
// if(Q.rear == p)
// Q.rear = Q.front;
// free(p);
// return OK;
//}
typedef struct {
int data[MAX_VERTEX_NUM];
int front, rear;
}Queue;
//队列顺序表的相关操作
//初始化
void InitQueue(Queue *Q)
{
Q->front = Q->rear = 0;
}
//入队
void EnQueue(Queue *Q, int e)
{
if ((Q->rear+1)%MAX_VERTEX_NUM == Q->front)
return ;
Q->data[Q->rear] = e;
Q->rear = (Q->rear+1)%MAX_VERTEX_NUM;
}
//判空
int QueueEmpty(Queue *Q)
{
if (Q->front == Q->rear)
return 1;
else
return 0;
}
//出队
void DeQueue(Queue *Q, int *e)
{
if (Q->front == Q->rear)
return ;
*e = Q->data[Q->front];
Q->front = (Q->front+1)%MAX_VERTEX_NUM;
}
void CreateALGraph(ALGraph *G) //构建图
{
ArcNode *p;
int i,j,k;
printf("输入顶点与边的数目:\n");
scanf("%d%d",&G->vexnum,&G->arcnum);
getchar();
printf("输入顶点值:\n");
for(i=1;i<=G->vexnum;i++)
{
//printf("input %dth vex(char) :\n");
scanf("%c",&G->vertices[i].data);
getchar();
G->vertices[i].firstarc=NULL;
}
//建立边表
printf("输入邻接表对应的下标:\n");
for(k=1;k<=G->arcnum;k++)
{
scanf("%d%d",&i,&j); //边对应的两个顶点下标并将俩顶点联系起来
p = (ArcNode *)malloc(sizeof(ArcNode));
p->adjvex = j;
p->nextarc = G->vertices[i].firstarc;
G->vertices[i].firstarc = p;
/*有向图只要上部分即可*/
p = (ArcNode*)malloc(sizeof(ArcNode));
p->adjvex = i;
p->nextarc = G->vertices[j].firstarc;
G->vertices[j].firstarc = p;
}
}
int visited[MAX_VERTEX_NUM]; //记录是否被访问
/*邻接表的深度遍历*/
void DFS(ALGraph G,int i)
{
int j;
ArcNode *p;
visited[i]=1; //将要访问的顶点置为1
printf("%c ",G.vertices[i].data); //输出各顶点
for(p = G.vertices[i].firstarc;p!=NULL;p=p->nextarc)
{
j = p->adjvex;
if(visited[j]==0) //深度探索
DFS(G,j);
}
}
void Is_connected(ALGraph G)
{
int i;
int count = 0;
for(i=1;i<=G.vexnum;i++)
visited[i]=0; //初始化0,未被访问
for(i=1;i<=G.vexnum;i++)
{
if(!visited[i])
{
printf("\n");
DFS(G,i);
count++; //记录连通图个数(>1)则整体是个非连通图
}
}
// if(count==1)
// printf("\nG is connected graph!");
// else
// printf("\nG is not connected graph!");
printf("\n连通图个数为:%d\n",count);
}
/*邻接表的广度遍历*/
void BFSTraverse(ALGraph g)
{
ArcNode *p;
Queue Q;
InitQueue(&Q);
for(int i = 1; i <= g.vexnum; i++)
{
visited[i] = 0;
}
for(int j = 1; j<=g.vexnum; j++)
{
if(!visited[j])
{
printf("%c ", g.vertices[j].data); //打印顶点,也可以其他操作
visited[j] = 1;
EnQueue(&Q,j);
while(!QueueEmpty(&Q))
{
int m;
DeQueue(&Q,&m); //访问点出队列
p = g.vertices[m].firstarc; //找到当前顶点边表链表头指针
while(p)
{
if(!visited[p->adjvex])
{
printf("%c ", g.vertices[p->adjvex].data);
visited[p->adjvex] = 1;
EnQueue(&Q, p->adjvex);
}
p = p->nextarc;
}
}
}
}
}
int flag = 0; //标志探寻点置0
int top = 0;
char path[MAX_VERTEX_NUM];
/*连通图的简单路径*/
void pathdfs(ALGraph G,int i,int j)
{
ArcNode *p;
int s,w;
visited[i]=1; //将顶点i加入当前路径
path[++top] = G.vertices[i].data;
if(!flag && path[top]==G.vertices[j].data)
flag = 1; //存在顶点i到顶点j的路径
if(flag) //找到
{
//输出当前路径上所有顶点
printf("\n");
for(s=1;s<=top;s++)
printf("%c\t",path[s]);
flag = 0;
}
else
for(p=G.vertices[i].firstarc;p;p=p->nextarc)
{
w = p->adjvex;
if(!visited[w])
pathdfs(G,w,j);
}
visited[i]=0; //每当顶点i回溯时,把visited[i]置为0,下次可通过顶点i寻找其他可能到达j的路径
top--; //删除顶点i
}
int main()
{
ALGraph G;
CreateALGraph(&G);
printf("-------------------\n");
printf("简单路径为:");
pathdfs(G,1,3);
printf("\n连通图的深度遍历为:");
Is_connected(G);
printf("\n连通图的广度遍历为:");
BFSTraverse(G);
return 0;
}