图的邻接表的遍历以及简单路径

 

#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;
}

    原文作者:数据结构之图
    原文地址: https://blog.csdn.net/lfb637/article/details/78577115
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞