無向圖和有向圖的深度遍歷和廣度遍歷


 

//

//  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("\b\b \n");

}

//廣度優先遍歷,非遞歸,輔助隊列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("\b\b \n");

}

 

 

 

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)輸入頂點數和弧數:\n");

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

        printf("如:1,2\n1,3\n輸入各邊弧尾和弧頭:\n");

        Create_Graph(&G);

        DFS_Traverse(G);

        BFS_Traverse(G);

        printf("圖的遍歷完畢,繼續進行嗎?(Y/N)");

        scanf("%c",&j);

    }

    

    return 0;

}

 

無向圖運行結果:

 

 

 有向圖運行結果:

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM