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

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

  • 1
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
使用深度优先搜索算法可以遍历的每一条路径。具体步骤如下: 1. 创建一个布尔型数组visited,用于记录每个顶点是否被访问过,初始值为false。 2. 从中的任意一个顶点开始遍历,将该顶点标记为已访问,并输出该顶点。 3. 遍历该顶点的邻接表,对于每个未访问过的邻接顶点,递归调用深度优先搜索算法。 4. 如果所有邻接顶点都已被访问过,则回溯到上一个顶点,继续遍历其它未访问过的邻接顶点。 5. 直到所有顶点都被访问过为止。 以下是Java代码示例: ```java public class Graph { private int V; private LinkedList<Integer>[] adj; public Graph(int V) { this.V = V; adj = new LinkedList[V]; for (int i = 0; i < V; i++) { adj[i] = new LinkedList<>(); } } public void addEdge(int v, int w) { adj[v].add(w); } public void DFS(int v, boolean[] visited, String path) { visited[v] = true; path += v + " "; if (isAllVisited(visited)) { System.out.println(path); } Iterator<Integer> it = adj[v].listIterator(); while (it.hasNext()) { int n = it.next(); if (!visited[n]) { DFS(n, visited, path); } } visited[v] = false; } public void traverse() { boolean[] visited = new boolean[V]; for (int i = 0; i < V; i++) { DFS(i, visited, ""); } } private boolean isAllVisited(boolean[] visited) { for (int i = 0; i < visited.length; i++) { if (!visited[i]) { return false; } } return true; } } ``` 在上面的代码中,DFS方法用于深度优先遍历,isAllVisited方法用于判断所有顶点是否都被访问过,traverse方法用于遍历的所有路径

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值