深度、广度优先搜索
文章目錄
- 二、圖的遍歷
- 2.1 深度優先搜索(DFS)
- DFS森林
- 應用
- 2.2 廣度優先搜索(BFS)
- 基本操作
- 應用
二、圖的遍歷
2.1 深度優先搜索(DFS)
DFS森林
Vertextype GetVex(ALGraph G, int v) {return G.vertices[v].data; }void DFSTree(ALGraph G, int v, CSTree& T) {int w, first;CSTree p, q=NULL;ArcNode* temp;visited[v] = TRUE;first = 1;temp = G.vertices[v].firstarc;while (temp != NULL){w = temp->adjvex;if (visited[w] == 0){p = (CSTree)malloc(sizeof(CSNode));p->e = GetVex(G, w); //原"GetVex(G,v)";將v改為w即可p->lchild = NULL;p->nextsibling = NULL;if (first){T->lchild = p; first = 0;}elseq->nextsibling = p;q = p;DFSTree(G, w, q);}temp = temp->nextarc;} }void DFSForest(ALGraph G, CSTree& T) {int v;CSTree p, q=NULL;T = NULL;for (v = 0; v < G.vexnum; v++)visited[v] = FALSE;for (v = 0; v < G.vexnum; v++){if (!visited[v]){p = (CSTree)malloc(sizeof(CSNode));p->e = GetVex(G, v);p->lchild = NULL;p->nextsibling = NULL;if (!T) T = p;else q->nextsibling = p;q = p;DFSTree(G, v, p);}} }應用
建立一無向圖的鄰接表存儲結構,并構造其對應的深度優先搜索生成樹或森林,按先序遍歷該二叉鏈表,輸出得到的序列
#include<stdio.h> #include<stdlib.h>#define TRUE 1 /*狀態碼預定義*/ #define FALSE 0 #define OK 1 #define ERROR 0 #define INFEASIBLE -1 #define OVERFLOW -2#define MAX_VERTAX_NUM 20 //最大頂點個數 typedef char Vertextype; //鄰接表類型 typedef struct ArcNode {int adjvex; //鄰接點域 struct ArcNode* nextarc; //指向下一個鄰接點的指針域 }ArcNode; //表頭結點類型 typedef struct VNode {Vertextype data; //頂點域 ArcNode* firstarc; //邊表頭指針 }VNode, AdjList[MAX_VERTAX_NUM]; //圖的類型 typedef struct {AdjList vertices; //鄰接表 int vexnum, arcnum; //頂點數 邊數 //int kind; }ALGraph; typedef struct CSNode {Vertextype e;CSNode* lchild, * nextsibling; }CSNode, * CSTree; int visited[MAX_VERTAX_NUM];int LocateVex(ALGraph G, char e) {int i;for (i = 0; i < G.vexnum; i++){if (G.vertices[i].data == e)return i;}return -1; }void CreateUDG(ALGraph& G) {int i, k, j;ArcNode* p, * s;char v1, v2; // printf("圖的種類已默認為無向圖\n"); // G.kind = 1;printf("請輸入頂點數和邊數:(空格區分)");scanf("%d%d", &G.vexnum, &G.arcnum);getchar();printf("開始建立頂點表\n");for (i = 0; i < G.vexnum; i++){printf("請輸入第%d個頂點的信息:", i + 1);G.vertices[i].data = getchar();getchar();G.vertices[i].firstarc = NULL;}printf("建立邊表\n");for (k = 0; k < G.arcnum; k++){printf("請輸入兩個頂點(例:ab代表a~b):");scanf("%c%c", &v1, &v2);getchar();i = LocateVex(G, v1);j = LocateVex(G, v2);p = (ArcNode*)malloc(sizeof(ArcNode));p->adjvex = j;p->nextarc = G.vertices[i].firstarc;G.vertices[i].firstarc = p;s = (ArcNode*)malloc(sizeof(ArcNode));s->adjvex = i;s->nextarc = G.vertices[j].firstarc;G.vertices[j].firstarc = s;}printf("邊表建立完成\n"); } //打印鄰接表 void DispGraph(ALGraph G) {int i;printf("打印鄰接表:\n");for (i = 0; i < G.vexnum; i++){printf("%d->", i);while (1){if (G.vertices[i].firstarc == NULL){printf("^");break;}printf("%d->", G.vertices[i].firstarc->adjvex);G.vertices[i].firstarc = G.vertices[i].firstarc->nextarc;}printf("\n");} }Vertextype GetVex(ALGraph G, int v) {return G.vertices[v].data; }void DFSTree(ALGraph G, int v, CSTree& T) {int w, first;CSTree p, q=NULL;ArcNode* temp;visited[v] = TRUE;first = 1;temp = G.vertices[v].firstarc;while (temp != NULL){w = temp->adjvex;if (visited[w] == 0){p = (CSTree)malloc(sizeof(CSNode));p->e = GetVex(G, w); //原"GetVex(G,v)";將v改為w即可p->lchild = NULL;p->nextsibling = NULL;if (first){T->lchild = p; first = 0;}elseq->nextsibling = p;q = p;DFSTree(G, w, q);}temp = temp->nextarc;} }void DFSForest(ALGraph G, CSTree& T) {int v;CSTree p, q=NULL;T = NULL;for (v = 0; v < G.vexnum; v++)visited[v] = FALSE;for (v = 0; v < G.vexnum; v++){if (!visited[v]){p = (CSTree)malloc(sizeof(CSNode));p->e = GetVex(G, v);p->lchild = NULL;p->nextsibling = NULL;if (!T) T = p;else q->nextsibling = p;q = p;DFSTree(G, v, p);}} }void PreOrderTraverse(CSTree T) {if (T == NULL) return;printf("%c", T->e);PreOrderTraverse(T->lchild);PreOrderTraverse(T->nextsibling); }int main() {ALGraph G; //圖CSTree T; //樹CreateUDG(G); //建圖DispGraph(G); //畫表DFSForest(G, T); //種樹printf("先序遍歷開始\n");PreOrderTraverse(T); //先序遍歷system("pause");return 0; }2.2 廣度優先搜索(BFS)
基本操作
int FirstAdjVex(MGraph G, int v) {int i;for (i = 0; i < G.vexnum; i++){if (G.arcs[v][i] == 1)return i;}return -1; }int NextAdjVex(MGraph G, int u, int w) {for (int i = w + 1; i < G.vexnum; i++){if (G.arcs[u][i] == 1)return i;}return -1; } void BFSTraverse(MGraph G) {SqQueue Q;int v, u, w, visited[MAX_VERTAX_NUM];for (v = 0; v < G.vexnum; ++v)visited[v] = FALSE;InitQueue(Q);for (v = 0; v < G.vexnum; v++){if (!visited[v]) //尚未訪問{visited[v] = TRUE; //訪問并標記cout << G.vexs[v]; //遍歷 輸出EnQueue(Q, v); //v 入隊while (!QueueEmpty(Q)){DeQueue(Q, u); //隊頭元素出隊并置為ufor (w = FirstAdjVex(G, u); w >= 0; w = NextAdjVex(G, u, w)) //遍歷邊{if (!visited[w]){visited[w] = TRUE;cout << G.vexs[w];EnQueue(Q, w);}}}}}cout << "廣度優先搜索完成" << endl; }應用
#include <iostream> using namespace std;#define TRUE 1 #define FALSE 0 #define OK 1 #define ERROR 0 #define INFEASIBLE -1 //不可執行#define STACK_INIT_SIZE 100 //存儲空間初始分配量 #define STACKINCREMENT 10 //存儲空間分配增量 #define MAXQSIZE 100 //最大隊列長度typedef int QElemType; typedef int Status;#define MAX_VERTAX_NUM 20 //最大頂點個數 #define INFINITYA 99999999typedef char VertexType; typedef int VRType; typedef int InfoType;typedef int AdjMatrix; typedef int QElemtype;/*--------單鏈隊列-隊列的順序存儲結構--------*/ /*線性表的單鏈表的存儲結構*/ typedef struct QNode {QElemType* base;int front;int rear; }SqQueue;Status InitQueue(SqQueue& Q) {Q.base = (QElemType*)malloc(MAXQSIZE * sizeof(QElemType));if (!Q.base)exit(OVERFLOW);Q.front = Q.rear = 0;return OK; }int QueueLength(SqQueue Q) {return (Q.rear - Q.front + MAXQSIZE) % MAXQSIZE; }/*插入元素e為Q的新的隊尾元素*/ Status EnQueue(SqQueue& Q, QElemType e) {if ((Q.rear + 1) % MAXQSIZE == Q.front)return ERROR;Q.base[Q.rear] = e;Q.rear = (Q.rear + 1) % MAXQSIZE;return OK; }/*若隊列不為空則刪除Q的隊頭元素,用e返回其值,并返回ok;否則返回ERROR*/ Status DeQueue(SqQueue& Q, QElemType& e) {if (Q.front == Q.rear)return ERROR;e = Q.base[Q.front];Q.front = (Q.front + 1) % MAXQSIZE;return OK; } /*判斷隊列是否為空*/ Status QueueEmpty(SqQueue Q) {if (Q.front == Q.rear)return TRUE;elsereturn FALSE; }//鄰接矩陣 typedef struct {VertexType vexs[MAX_VERTAX_NUM];AdjMatrix arcs[MAX_VERTAX_NUM][MAX_VERTAX_NUM];int vexnum, arcnum; }MGraph;int LocateVex(MGraph G, VertexType e) {int i;for (i = 0; i < G.vexnum; i++){if (G.vexs[i] == e)return i;}return -1; }Status CreateDG(MGraph& G) {int i, j, k;char v1, v2;cout << "請輸入圖的頂點個數(vexnum),邊數(arcnum)";cin >> G.vexnum >> G.arcnum;getchar();cout << "請輸入頂點(例:abcd):";for (i = 0; i < G.vexnum; i++)G.vexs[i] = getchar();getchar();for (i = 0; i < G.vexnum; i++)for (j = 0; j < G.vexnum; j++)G.arcs[i][j] = INFINITYA;for (k = 0; k < G.arcnum; k++){cout << k;cout << "請輸入兩個頂點:";cin >> v1 >> v2;getchar();i = LocateVex(G, v1);j = LocateVex(G, v2);G.arcs[i][j] = 1;}return OK; }int FirstAdjVex(MGraph G, int v) {int i;for (i = 0; i < G.vexnum; i++){if (G.arcs[v][i] == 1)return i;}return -1; }int NextAdjVex(MGraph G, int u, int w) {for (int i = w + 1; i < G.vexnum; i++){if (G.arcs[u][i] == 1)return i;}return -1; } void BFSTraverse(MGraph G) {SqQueue Q;int v, u, w, visited[MAX_VERTAX_NUM];for (v = 0; v < G.vexnum; ++v)visited[v] = FALSE;InitQueue(Q);for (v = 0; v < G.vexnum; v++){if (!visited[v]) //尚未訪問{visited[v] = TRUE; //訪問并標記cout << G.vexs[v]; //遍歷 輸出EnQueue(Q, v); //v 入隊while (!QueueEmpty(Q)){DeQueue(Q, u); //隊頭元素出隊并置為ufor (w = FirstAdjVex(G, u); w >= 0; w = NextAdjVex(G, u, w)) //遍歷邊{if (!visited[w]){visited[w] = TRUE;cout << G.vexs[w];EnQueue(Q, w);}}}}}cout << "廣度優先搜索完成" << endl; }int main() {MGraph G;CreateDG(G);BFSTraverse(G); return 0; }···總結
- 上一篇: 栈与队列基本操作及其应用
- 下一篇: 图的基本操作及其相关应用