• 无向图和有向图的深度遍历和广度遍历


     

    //

    //  main.cpp

    //  Grpah_DFS_BFS

    //

    //  Created by duanqibo on 2019/7/3.

    //  Copyright © 2019年 duanqibo. All rights reserved.

    //  无向图和有向图的深度遍历和广度遍历

    #include <iostream>

    #include <stdio.h>

    #include <stdlib.h>

    #define MaxVerNum 20  //图的最大顶点数

    #define MaxSize 30  //队列的最大容量

    typedef enum {False,True} Bool;

    typedef struct ArcNode

    {

        int adjvex;  //该弧所指向的顶点的位置

        struct ArcNode *nextarc;   //指向下一条弧的指针

    }ArcNode;   //弧结点

    typedef struct{

        ArcNode *AdjList[MaxVerNum];  //指向第一条依附该顶点的弧的指针

        int vexnum,arcnum;  //图的当前顶点和弧数

        int GraphKind;   //图的种类,无向图-0,有向图-1

    }Graph;

    typedef struct  //队列的结构体

    {

        int elem[MaxSize];  //数据域

        int front,rear;  //队头,队尾指针

    }SeQueue;  //

    Bool visited[MaxVerNum];  //全局变量--访问标志数组

    void Create_Graph(Graph *G)

    {

        int i,start,end;

        ArcNode *s;

        for(i=1;i<=(*G).vexnum;i++)

            (*G).AdjList[i]=NULL;  //初始化指针数组

        for(i=1;i<=(*G).arcnum;i++)

        {

            scanf("%d%d",&start,&end);  //输入弧的起点和终点

            s=(ArcNode *)malloc(sizeof(ArcNode));  //生成一个弧结点

            s->nextarc=(*G).AdjList[start];

            s->adjvex=end;

            (*G).AdjList[start]=s;

            if((*G).GraphKind==0)  //若是无向图,再插入到终点的弧链中

            {

                s=(ArcNode *)malloc(sizeof(ArcNode));

                s->nextarc=(*G).AdjList[end];

                s->adjvex=start;

                (*G).AdjList[end]=s;

            }

        }

    }

    int First_AdjVex(Graph G,int v)  //找第vi个顶点的第一个邻接顶点

    {

        if(!G.AdjList[v])

            return 0;

        else

            return (G.AdjList[v]->adjvex);

    }

    int Next_AdjVex(Graph G,int v,int u) //找第vi个顶点相对u的下一个邻接顶点

    {

        ArcNode *p;

        p=G.AdjList[v];

        while(p->adjvex!=u)  //在顶点vi的弧链中找到顶点u

            p=p->nextarc;

        if(p->nextarc==NULL)  //若已是最后一个顶点,返回0

            return 0;

        else

            return (p->nextarc->adjvex);  //返回下一个邻接顶点的序号

    }

    void Init_Queue(SeQueue *Q)

    {

        (*Q).front=(*Q).rear;   //初始化队列

    }

    Bool Empty_Queue(SeQueue Q)  //判断队列是否为空

    {

        if(Q.front==Q.rear)

            return True;

        else

            return False;

    }

    Bool In_Queue(SeQueue *Q,int ch)//入队操作,成功True

    {

        if(((*Q).rear+1)%MaxSize==(*Q).front)

            return False;

        (*Q).elem[(*Q).rear]=ch;

        (*Q).rear=((*Q).rear+1)%MaxSize;

        return True;

    }

    Bool Out_Queue(SeQueue *Q,int *ch)//出队操作,成功True

    {

        if((*Q).front==(*Q).rear)

            return False;

        (*ch)=(*Q).elem[(*Q).front];

        (*Q).front=((*Q).front+1)%MaxSize;

        return True;

    }

    void DFS(Graph G,int i)  //从第i个顶点出发递归的深度遍历图

    {

        int w;

        visited[i]=True;  //访问第i个顶点

        printf("%d->",i);

        for(w=First_AdjVex(G,i);w;w=Next_AdjVex(G, i, w))

            if(!visited[w])

                DFS(G,w);  //对尚未访问的邻接顶点w调用DFS

    }

    void DFS_Traverse(Graph G)  //深度优先遍历算法

    {

        int i;

        printf("深度优先遍历:");

        for(i=1;i<G.vexnum;i++)

            visited[i]=False;  //访问标志数组初始化

        for(i=1;i<G.vexnum;i++)

            if(!visited[i])

                DFS(G,i);

        printf(" ");

    }

    //广度优先遍历,非递归,辅助队列Q和访问椟志数组visited

    void BFS_Traverse(Graph G)

    {

        int i,u,w;

        SeQueue Q;

        printf("广度优先遍历:");

        for(i=1;i<=G.vexnum;i++)

            visited[i]=False;  //访问标志数组初始化

        Init_Queue(&Q);  //初始化队列

        for(i=1;i<=G.vexnum;i++)

            if(!visited[i])

            {

                visited[i]=True;  //访问顶点vi

                printf("%d->",i);

                In_Queue(&Q, i);  //将序号i入队

                while(!Empty_Queue(Q))  //若队列不空,继续

                {

                    Out_Queue(&Q, &u);//将队首元素出队并置u

                    for(w=First_AdjVex(G, u);w;w=Next_AdjVex(G, u, w))

                        if(!visited[w])  //对u的尚未访问的邻接顶点w进行访问并入队列

                        {

                            visited[w]=True;

                            printf("%d->",w);

                            In_Queue(&Q, w);

                        }

                        

                }

            }

        printf(" ");

    }

    int main(int argc, const char * argv[]) {

        Graph G;

        char j='y';

        //system("cls");

        while(j!='N' && j!='n')

        {

            printf("输入0或1(无向图-0,有向图-1):");

            scanf("%d",&G.GraphKind);

            printf("(如:4,3)输入顶点数和弧数: ");

            scanf("%d%d",&G.vexnum,&G.arcnum);

            printf("如:1,2 1,3 输入各边弧尾和弧头: ");

            Create_Graph(&G);

            DFS_Traverse(G);

            BFS_Traverse(G);

            printf("图的遍历完毕,继续进行吗?(Y/N)");

            scanf("%c",&j);

        }

        

        return 0;

    }

    无向图运行结果:

     有向图运行结果:

  • 相关阅读:
    参加过的面试题目总结
    小论文实验讨论——不同的分类算法
    【设计模式】行为型07备忘录模式(Memento Pattern)
    【设计模式】行为型06命令模式(Command Pattern)
    【设计模式】行为型05责任链模式(Chain of responsibility Pattern)
    【设计模式】行为型04迭代器模式(Iterator Pattern)
    【设计模式】行为型03观察者模式(Observer Pattern)
    【设计模式】行为型02模板方法模式(Template Method Patten)
    【JVM】02垃圾回收机制
    【死磕线程】线程同步机制_java多线程之线程锁
  • 原文地址:https://www.cnblogs.com/duanqibo/p/11126221.html
Copyright © 2020-2023  润新知