1. 程式人生 > >實驗6 圖的遍歷

實驗6 圖的遍歷

#include<stdio.h>
#include<stdlib.h>

#define MaxVex 255
#define TRUE   1
#define FALSE  0

typedef char VertexType;  //頂點型別用的是char型
typedef int Bool;
Bool visited[MaxVex];  //用陣列表示是否訪問

typedef struct EdgeNode {
    int adjvex;    //鄰接點在頂點陣列中的下標
    struct EdgeNode *next;   //指向下一個鄰接點
}EdgeNode;

typedef struct VertexNode { //頭節點
    VertexType data;  //頂點的資訊
    EdgeNode *firstedge;
}VertexNode,AdjList[MaxVex]; //頂點陣列

typedef struct Graph{
    AdjList adjList;
    int numVertexes,numEdges;  //圖的結點數以及邊數
}Graph,*GraphAdjList;


//有關佇列的用到的函式
typedef struct LoopQueue{
    int data[MaxVex];
    int front,rear;
}LoopQueue,*Queue;

//佇列初始化
void initQueue(Queue &Q){
    Q->front=Q->rear=0;
}
//判斷佇列是否為空
Bool QueueEmpty(Queue &Q){
    if(Q->front == Q->rear){
        return TRUE;
    }else{
        return FALSE;
    }
}
//判斷佇列是否滿
Bool QueueFull(Queue &Q){
    if((Q->rear+1)%MaxVex == Q->front){
        return TRUE;
    }else{
        return FALSE;
    }
}
//在佇列的隊尾插入元素
void EnQueue(Queue &Q,int e){
    if(!QueueFull(Q)){
        Q->data[Q->rear] = e;
        Q->rear = (Q->rear+1)%MaxVex;
    }
}
//在佇列的隊頭刪除元素
void DeQueue(Queue &Q,int *e){
    if(!QueueEmpty(Q)){
        *e = Q->data[Q->front];
        Q->front = (Q->front+1)%MaxVex;
    }
}

 //建立圖的鄰接表結構(無向圖)
void CreateALGraph(GraphAdjList &G){
    int i, j, k;
    if(G==NULL){
        G = (GraphAdjList)malloc(sizeof(Graph));
    }

    printf("輸入圖的結點數以及邊數: ");
    scanf("%d%d",&G->numVertexes,&G->numEdges);
    fflush(stdin);
   // 輸入圖的結點數以及邊數
    printf("輸入各個頂點的資料:\n");
    for (i=0; i<G->numVertexes; ++i){
        printf("頂點%d: ",i+1);
        scanf("%c", &(G->adjList[i].data));
        G->adjList[i].firstedge = NULL;
        fflush(stdin);
    }//char型的頂點資料,以161頁的(a)的圖為例子

    for (k=0; k<G->numEdges; ++k){
        printf("輸入(vi,vj)上的頂點序號: ");
        scanf("%d%d",&i,&j);
    //按照(vi,vj)的形式輸入頂點的序號
        EdgeNode *ptrEdgeNode = (EdgeNode*)malloc(sizeof(EdgeNode));
        ptrEdgeNode->adjvex = j;
        ptrEdgeNode->next = G->adjList[i].firstedge;
        G->adjList[i].firstedge = ptrEdgeNode;
        ptrEdgeNode = (EdgeNode*)malloc(sizeof(EdgeNode));
        ptrEdgeNode->adjvex = i;
        ptrEdgeNode->next = G->adjList[j].firstedge;
        G->adjList[j].firstedge = ptrEdgeNode;
    }//建立圖的鄰接表
}



 //遞迴深度遍歷的DSF函式
void DFS(GraphAdjList &G, int i){
    visited[i] = TRUE;
    printf("%c ", G->adjList[i].data);

    EdgeNode *p = G->adjList[i].firstedge;
    while(p){
        if(!visited[p->adjvex]){
            DFS(G,p->adjvex);
        }
        p= p->next;
    }
}


//深度優先遍歷
void DFSTraverse(GraphAdjList &G){
    int i;
    for (i=0; i<G->numVertexes; ++i){
        visited[i] = FALSE;
    }
    for (i=0; i<G->numVertexes; ++i){
        if(!visited[i]){
            DFS(G,i);
        }
    }
}


//廣度優先遍歷
void BFSTraverse(GraphAdjList &G){
    int i;
    Queue Q = (Queue)malloc(sizeof(LoopQueue));

    for (i=0; i<G->numVertexes; ++i){
        visited[i] = FALSE; //沒有被訪問的設定為FALSE
    }
    initQueue(Q);

    for (i=0; i<G->numVertexes; ++i){
        if(!visited[i]){
            visited[i] = TRUE;
            printf("%c ", G->adjList[i].data);
            EnQueue(Q, i);
    //如果該節點之前沒被訪問過,設定為TRUE,並且入隊
            while (!QueueEmpty(Q)){
                DeQueue(Q, &i);
                EdgeNode *p = G->adjList[i].firstedge;
                while (p){
                    if (!visited[p->adjvex]){
                        visited[p->adjvex] = TRUE;
                        printf("%c ", G->adjList[p->adjvex].data);
                        EnQueue(Q, p->adjvex);
                    }
                    p = p->next;
                }
            }
        }
    }
}

//主函式
int main(){
    GraphAdjList G = NULL;
    CreateALGraph(G);
    printf("\n圖的深度優先遍歷: ");
    DFSTraverse(G);
    printf("\n圖的廣度優先遍歷: ");
    BFSTraverse(G);
    printf("\n");
    return 0;
}