用邻接表实现DFS和BFS

#include <stdio.h>
#include <stdlib.h>
#define MAXVERTEX 10
typedef char VertexType;                //顶点类型
typedef int EdgeType;                   //边的类型
typedef int ElemType;                   //队列中元素类型
typedef struct EdgeNode
{
    int adjvex;
    EdgeType weight;
    struct EdgeNode *next;
}EdgeNode;                              //在邻接表中存放邻接顶点下标值的结点
typedef struct VertexNode
{
    int Flag;
    int vertex;
    VertexType data;
    EdgeNode *firstedge;
}VertexNode,AdjList[MAXVERTEX];         //定义一个MAXVERTEX个顶点的邻接表
typedef struct GraphAdjList
{
    AdjList adjList;
    int numVertex;
    int numEdge;
}GraphAdjList;                          //定义一个图

typedef struct QNode
{
    ElemType qData;
    struct QNode *nextNode;
}QNode;                                 //定义队列的结点
typedef struct QueueList
{
    QNode *front;
    QNode *rear;
}QueueList,*queue;                      //定义一个队列

                                        //初始化队列
void InitQueue(QueueList *Q)
{
    Q->front = (QNode*)malloc(sizeof(QNode));
    if( Q->front == NULL )
    {
        printf("Error!");
        exit(0);
    }
    Q->rear = Q->front;
//    Q->rear = NULL;
    Q->front->nextNode = NULL;
}

                                        //插入一个结点到队列
void InsertQueue(QueueList *Q,ElemType *e)
{
    QNode *p;
    p = (QNode *)malloc(sizeof(QNode));
    p->qData = *e;
    p->nextNode = NULL;
    Q->rear->nextNode = p;
    Q->rear = p;
}

                                        //删除队列中的结点(出队列)
void DeleteQueue(QueueList *Q,ElemType *e)
{
    QNode *s;
    if(Q->front == Q->rear)
    {
        return;
    }
    s = Q->front->nextNode;
    *e = s->qData;
    Q->front->nextNode = s->nextNode;
    if(Q->front->nextNode == NULL)
    {
        Q->rear = Q->front;
    }
    free(s);
    return;
}

void CreateGraph(GraphAdjList *G)           //构建一个我们要遍历的图
{
    int i = 0,j = 0,k = 0;
    EdgeNode *s;
    VertexType c;
    printf("请输入图的顶点数和边数,中间用英文逗号隔开 :\n");
    scanf("%d,%d",&G->numVertex,&G->numEdge);
    printf("请输入各个顶点中存放的数据:\n");
    fflush(stdin);
    scanf("%c",&c);
    while(i < G->numVertex)
    {
        if(c == ‘\n‘)
        {
            break;
        }
        G->adjList[i].data = c;
        G->adjList[i].Flag = 0;
        G->adjList[i].vertex = i;
        G->adjList[i].firstedge = NULL;
        i++;
        scanf("%c",&c);
    }
        fflush(stdin);
        for(k = 0;k < G->numEdge;k++)
        {
            printf("请输入边Vi~Vj依附的顶点下标 i 和 j :\n");
            scanf("%d,%d",&i,&j);
            s = (EdgeNode*)malloc(sizeof(EdgeNode));
            s->adjvex = j;
            s->next = G->adjList[i].firstedge;
            G->adjList[i].firstedge = s;
            s = (EdgeNode*)malloc(sizeof(EdgeNode));
            s->adjvex = i;
            s->next = G->adjList[j].firstedge;
            G->adjList[j].firstedge = s;
        }
}
                                            //查看邻接表是否构建的正确,这个函数只是为了验证
void print(GraphAdjList *G)
{
    int i = 0;
    EdgeNode *p;
    for(i = 0;i < G->numVertex;i++)
    {
        printf("\n %d->",i);
        p = G->adjList[i].firstedge;
        while(p)
        {
            printf("%d->",p->adjvex);
            p = p->next;
        }
        printf("End\n");
    }
}

                                            //DFS遍历
void DFSTraverse(GraphAdjList *G,int i)
{
    int j = 0;
    EdgeNode *p;
    G->adjList[i].Flag = 1;
    printf("%c->",G->adjList[i].data);
    p = G->adjList[i].firstedge;
    while(p != NULL)
    {
        if(G->adjList[p->adjvex].Flag == 0)
        {
            DFSTraverse(G,p->adjvex);
        }
        p = p->next;
    }
}
                                            //判断队列是否为空
int QueueEmpty(QueueList *Q)
{
    if(Q->front == Q->rear)
        return 0;
    else
        return 1;
}
                                            //BFS遍历
void BFSTraverse(GraphAdjList *G)
{
    int i = 0,k = 0,flag = 0;
    EdgeNode *s;
    QueueList Q;
    InitQueue(&Q);
    for(i = 0;i < G->numVertex;i++)
    {
        G->adjList[i].Flag = 0;
    }
    for(i = 0;i < G->numVertex;i++)
    {
        if(G->adjList[i].Flag == 0)
        {
            G->adjList[i].Flag = 1;
//            printf("%c ",G->adjList[i].data);
            InsertQueue(&Q,&i);
            while(QueueEmpty(&Q))
            {
                DeleteQueue(&Q,&i);
                printf("%c->",G->adjList[i].data);
                s = G->adjList[i].firstedge;
                while(s != NULL)
                {
                    k = s->adjvex;
                    if(G->adjList[k].Flag == 0)
                    {
                        G->adjList[k].Flag = 1;
//                        printf("%c ",G->adjList[k].data);
                        InsertQueue(&Q,&(s->adjvex));
                    }
                    s = s->next;
                }

            }
        }
    }
    printf("End\n");
}

int main()
{
    int k = 0;                               //深度优先遍历从第1个顶点(按输入顺序)开始
    GraphAdjList *G;
    CreateGraph(G);
    printf("\n顶点的邻接表为:\n");
    print(G);                                //按照头插法得到的邻接表
    printf("\nDFS的结果是:\n");
    DFSTraverse(G,k);                        //深度优先遍历
    printf("End\n");
    printf("\nBFS的结果是:\n");
    BFSTraverse(G);                         //广度优先遍历
    return;
}

  

时间: 2024-10-04 20:57:41

用邻接表实现DFS和BFS的相关文章

PAT1013. Battle Over Cities(邻接矩阵、邻接表分别dfs)

//采用不同的图存储结构结构邻接矩阵.邻接表分别dfs,我想我是寂寞了吧,应该试试并查集,看见可以用并查集的就用dfs,bfs代替......怕了并查集了 //邻接矩阵dfs #include<cstdio>#include<algorithm>using namespace std;const int maxn=1001;int g[maxn][maxn];int n,tmp;bool vis[maxn];void dfs(int v){ vis[v]=true; for(int

(编程训练)再回首,数据结构——无向图的邻接矩阵表示、DFS、BFS

最近在复习数据结构,顺便看看大一的时候写的代码,看完之后比当初有了更加深刻的体会. 希望这些能提供给初学者一些参考. 在VC++6.0下可运行,当初还写了不少注释. [问题描述] 建立图的邻接矩阵存储结构,实现图的遍历 [基本要求] ·功能:建立图的邻接矩阵存储结构,实现图的BFS.DFS ·输入:输入连通图的顶点数.顶点信息.边数.顶点对序列及遍历的起始顶点序号 ·输出:图的广度优先搜索序列.深度优先搜索 [模块划分] 1. 建立有向图的邻接表 CreateAdjMatrix() 2. 以邻接

JAVA实现图的邻接表以及DFS

一:定义邻接表结构储存图 package 图的遍历; //邻接表实现图的建立 //储存边 class EdgeNode { int index; // 习惯了用index,其实标准写法是(adjVertex) int value; // 权值 EdgeNode nextArc; // 指向下一条弧 } // 邻接表节点的类型 class VertexNode { String name; EdgeNode firstArc = new EdgeNode(); // 指向第一条弧 } public

邻接表的dfs遍历

//输入样例 /* 5 0 AB AD AC CD BE DE */ //输出 /* Please Input the edge x-->y:AB AD AC CD BE DE A 1 2 3 B 0 4 C 0 3 D 0 2 4 E 1 3 */ //dfs测试数据 /* 8 0 Please Input the edge x-->y:AB AC BD BE DH EH HF HG FC GC CA A 1 2 2 B 0 3 4 C 0 0 5 6 D 1 7 E 1 7 F 2 7 G

POJ 1724 ROADS(使用邻接表和优先队列的BFS求解最短路问题)

题目链接: https://cn.vjudge.net/problem/POJ-1724 N cities named with numbers 1 ... N are connected with one-way roads. Each road has two parameters associated with it : the road length and the toll that needs to be paid for the road (expressed in the num

基于邻接矩阵和邻接表的两种方法实现无向图的BFS和DFS

广度优先搜索(Breadth-First-Search)和深度优先搜索(Deep-First-Search)是搜索策略中最经常用到的两种方法,特别常用于图的搜索. BFS的思想: 从一个图的某一个顶点V0出发,首先访问和V0相邻的且未被访问过的顶点V1.V2.--Vn,然后依次访问与V1.V2--Vn相邻且未被访问的顶点.如此继续,找到所要找的顶点或者遍历完整个图.我们采用队列来存储访问过的节点. DFS的思想: 深度优先搜索所遵循的策略就是尽可能"深"的在图中进行搜索,对于图中某一个

图的 DFS 与 BFS 复杂度分析

DFS的复杂度分析: 对于邻接表的存储方式:因为邻接表中每条链表上的从第2个结点到表尾结点一定是表头结点的邻接点,所以遍历表头结点的邻接的过程中只需要遍历这些顶点即可,无需遍历其他的顶点,所以遍历某个顶点的所有邻接点的复杂度为O(ei), ei为每个顶点的邻接点个数,也就是每条链表的边数.所以邻接表版的 dfs 遍历所有邻接点的时间复杂度为 O(e1 + e2 + e3 + .... + en) ,因为所有边数之和为 E , 所以时间复杂度为 O(E) , 又因为访问每个顶点都必须被访问一次,

邻接表实现Dijkstra算法以及DFS与BFS算法

//============================================================================ // Name : ListDijkstra.cpp // Author : fffff // Version : // Copyright : Your copyright notice // Description : Hello World in C++, Ansi-style //==========================

数据结构学习笔记05图 (邻接矩阵 邻接表--&gt;BFS DFS)

数据结构之图 图(Graph) 包含 一组顶点:通常用V (Vertex) 表示顶点集合 一组边:通常用E (Edge) 表示边的集合 边是顶点对:(v, w) ∈E ,其中v, w ∈ V 有向边<v, w> 表示从v指向w的边(单行线) 不考虑重边和自回路 无向图:边是无向边(v, w) 有向图:边是有向边<v, w> 连通:如果从V到W存在一条(无向)路径,则称V和W是连通的 连通图(Connected Graph):如果对于图的任一两个顶点v.w∈V,v和w都是连通的,则称