圖的建立、廣度優先搜尋、深度優先搜尋
阿新 • • 發佈:2019-01-29
#include <iostream> /*圖的儲存結構:鄰接連結串列、鄰接矩陣*/ /******************圖的資料結構***************/ typedef char ElemType; const int WHITE = 0; const int BLACK = 1; const int MAX_VERTEX = 30; const int MAX_ARC = 900; /*邊的資料結構*/ typedef struct arc_node { int position;//儲存邊的另一個頂點下標 int weight;//邊的權重 struct arc_node *next;//指向下一條邊 }ANode, *pArc; /*頂點的資料結構*/ typedef struct vertex_node { ElemType data; pArc first_arc;//指向第一條弧 }VNode, *pVNode; /*圖的資料結構*/ typedef struct graphic_node { int vertex_num;//頂點數量 int arc_num;//邊的數量 pVNode vertex[MAX_VERTEX];//用來存放頂點的陣列 }Graphic, *pGNode; void create_graphic(pGNode g, int direction);//建立圖,direction=0無向圖,=1有向圖 /******************圖的遍歷***************/ /*1、廣度優先搜尋(類似於樹的按層次遍歷) 基本思想:在已發現節點和未發現節點的邊界上,沿其廣度方向向外擴充套件,也就是說訪問完距離源節點 為k的節點再去訪問距離為k+1的節點 */ void bfs(Graphic g, int source);//給定圖g和起始遍歷位置 /*2、深度優先搜尋(類似於樹的先根遍歷) 基本思想:只要可能就在圖中儘量深入,總是對最近才發現的節點v沿其出發邊進行探索 直到該節點的所有出發邊都被發現為止,搜尋則回溯到v節點的前驅節點 */ void dfs(Graphic g); void dfs_visit(Graphic g, int source); int visit[MAX_VERTEX] = { WHITE };//用來記錄節點是否被訪問 /*輔助資料結構:佇列*/ struct queue_node { pVNode data; struct queue_node *next; }; typedef struct queue { struct queue_node *front; struct queue_node *tail; }Queue; /*要想修改內容必須傳指標,要想修改內容指向的值可以不傳指標*/ void init_queue(Queue *q); bool isempty_queue(Queue q); void insert_queue(Queue *q, pVNode e); bool delete_queue(Queue *q, pVNode *e);//當刪除最後一個元素的時候一定要修改尾部指標 using namespace std; int main() { Graphic undirec_g, direc_g; cout << "*****************建立一個無向圖*************" << endl; create_graphic(&undirec_g, 0); cout <<endl<< "廣度優先遍歷:" << endl; bfs(undirec_g, 0); cout << endl << "深度優先遍歷:" << endl; dfs(undirec_g); cout << endl << "*****************建立一個有向圖*************" << endl; create_graphic(&direc_g, 1); cout << endl << "廣度優先遍歷:" << endl; bfs(direc_g, 0); cout << endl << "深度優先遍歷:" << endl; dfs(direc_g); cout << endl; } void create_graphic(pGNode g, int direction)//direction = 0表示建立的是無向圖,非0值是有向圖 { cout << "輸入頂點數" << endl; cin >> g->vertex_num; cout << "輸入邊數" << endl; cin >> g->arc_num; int i; cout << "輸入" << g->vertex_num << "個頂點" << endl; for (i = 0; i < g->vertex_num; i++) { g->vertex[i] = (pVNode)malloc(sizeof(VNode)); cin >> (g->vertex[i]->data); g->vertex[i]->first_arc = NULL; } cout << "輸入" << g->arc_num << "個邊和邊的權重(例如:輸入0 1 20表示下標為0和下標為1的頂點有一條邊且權重為20)" << endl; for (i = 0; i < g->arc_num; i++) { int x, y, w; cin >> x >> y >> w; pArc temp1 = (pArc)malloc(sizeof(ANode)); temp1->position = y; temp1->weight = w; /*將邊加入到連結連結串列中*/ temp1->next = g->vertex[x]->first_arc; g->vertex[x]->first_arc = temp1; if (direction == 0)//說明是無向圖 { pArc temp2 = (pArc)malloc(sizeof(ANode)); temp2->position = x; temp2->weight = w; temp2->next = g->vertex[y]->first_arc; g->vertex[y]->first_arc = temp2; } } } void bfs(Graphic g, int source)//給定圖g和起始遍歷位置 { int visit[MAX_VERTEX] = { WHITE };//初始化為白色,說明所有頂點沒有被訪問,訪問之後變為黑色 Queue q; init_queue(&q); insert_queue(&q, g.vertex[source]); visit[source] = BLACK; /*如果佇列不為空則從佇列中取出元素*/ while (!isempty_queue(q)) { pVNode temp; delete_queue(&q, &temp); /*列印輸出該節點資料*/ cout << temp->data << " "; /*如果節點所連線的其它節點沒有被訪問,則加入到佇列中*/ pArc x = temp->first_arc; while (x != NULL) { int position = x->position; if (visit[position] == WHITE) { insert_queue(&q, g.vertex[position]); visit[position] = BLACK; } x = x->next; } } } void dfs(Graphic g) { for (int i = 0; i < g.vertex_num; i++) visit[i] = WHITE;//初始化為白色,意味著沒有被訪問 for (int i = 0; i < g.vertex_num; i++) { if (visit[i] == WHITE) dfs_visit(g, i); } } void dfs_visit(Graphic g, int source) { if (visit[source] == BLACK) return; pVNode x = g.vertex[source]; cout << x->data; visit[source] = BLACK; pArc y = x->first_arc; while (y != NULL) { dfs_visit(g, y->position); y = y->next; } } void init_queue(Queue *q) { queue_node *temp = (queue_node *)malloc(sizeof(queue_node)); temp->next = NULL; q->front = q->tail = temp; } bool isempty_queue(Queue q) { if (q.front->next == NULL) return true; return false; } void insert_queue(Queue *q, pVNode e) { /*動態分配一個佇列節點*/ queue_node *x = (queue_node *)malloc(sizeof(queue_node)); x->data = e; x->next = NULL; /*將節點插入到佇列的尾部*/ q->tail->next = x; q->tail = x; } bool delete_queue(Queue *q, pVNode *e) { if (isempty_queue(*q)) return false; queue_node *temp = q->front->next; *e = temp->data; q->front->next = temp->next; if (temp->next == NULL)//到了隊尾 q->tail = q->front; free(temp); return true; }