1. 程式人生 > >數據結構-深度遍歷和廣度遍歷(轉)

數據結構-深度遍歷和廣度遍歷(轉)

指針 void 邊表 當前 初始化 循環隊列 logs == ont

本文轉自http://blog.csdn.net/wingofeagle/article/details/13020373

深度遍歷:

從圖中某個頂點v出發,訪問此頂點,然後從v的未被訪問的鄰接點出發深度優先遍歷圖,直至圖中所有和v有路徑相通的頂點都被訪問到。

其更適合:目標比較明確,以找到目標為主要目的的情況。

廣度遍歷:

類似於樹中的層序遍歷,首先遍歷完和某一頂點v相連的所有頂點,然後再遍歷和這些頂點相連的頂點,以此類推。

其更適合於:不斷擴大遍歷範圍時找到相對最優解的情況。

具體代碼如下:

  1 // GraphSearch.cpp : Defines the entry point for the console application.  
2 // 3 4 #include "stdafx.h" 5 #include "stdio.h" 6 7 #define OK 1 8 #define ERROR 0 9 #define TRUE 1 10 #define FALSE 0 11 12 typedef int Status; /* Status是函數的類型,其值是函數結果狀態代碼,如OK等 */ 13 typedef int Boolean; /* Boolean是布爾類型,其值是TRUE或FALSE */ 14 15 typedef char
VertexType; /* 頂點類型應由用戶定義 */ 16 typedef int EdgeType; /* 邊上的權值類型應由用戶定義 */ 17 18 #define MAXSIZE 9 /* 存儲空間初始分配量 */ 19 #define MAXEDGE 15 20 #define MAXVEX 9 21 #define INFINITY 65535 22 23 typedef struct 24 { 25 VertexType vexs[MAXVEX]; /* 頂點表 */ 26 EdgeType arc[MAXVEX][MAXVEX];/*
鄰接矩陣,可看作邊表 */ 27 int numVertexes, numEdges; /* 圖中當前的頂點數和邊數 */ 28 }MGraph; 29 30 /* 用到的隊列結構與函數********************************** */ 31 32 /* 循環隊列的順序存儲結構 */ 33 typedef struct 34 { 35 int data[MAXSIZE]; 36 int front; /* 頭指針 */ 37 int rear; /* 尾指針,若隊列不空,指向隊列尾元素的下一個位置 */ 38 }Queue; 39 40 /* 初始化一個空循環隊列Q */ 41 Status InitQueue(Queue *Q) 42 { 43 Q->front=0; 44 Q->rear=0; 45 return OK; 46 } 47 48 /* 若隊列Q為空隊列,則返回TRUE,否則返回FALSE */ 49 Status QueueEmpty(Queue Q) 50 { 51 if(Q.front==Q.rear) /* 隊列空的標誌 */ 52 return TRUE; 53 else 54 return FALSE; 55 } 56 57 /* 若隊列未滿,則插入元素e為Q新的隊尾元素 */ 58 Status EnQueue(Queue *Q,int e) 59 { 60 if ((Q->rear+1)%MAXSIZE == Q->front) /* 隊列滿的判斷 */ 61 return ERROR; 62 Q->data[Q->rear]=e; /* 將元素e賦值給隊尾 */ 63 Q->rear=(Q->rear+1)%MAXSIZE;/* rear指針向後移一位置, */ 64 /* 若到最後則轉到數組頭部 */ 65 return OK; 66 } 67 68 /* 若隊列不空,則刪除Q中隊頭元素,用e返回其值 */ 69 Status DeQueue(Queue *Q,int *e) 70 { 71 if (Q->front == Q->rear) /* 隊列空的判斷 */ 72 return ERROR; 73 *e=Q->data[Q->front]; /* 將隊頭元素賦值給e */ 74 Q->front=(Q->front+1)%MAXSIZE; /* front指針向後移一位置, */ 75 /* 若到最後則轉到數組頭部 */ 76 return OK; 77 } 78 /* ****************************************************** */ 79 80 81 void CreateMGraph(MGraph *G) 82 { 83 int i, j; 84 85 G->numEdges=15; 86 G->numVertexes=9; 87 88 /* 讀入頂點信息,建立頂點表 */ 89 G->vexs[0]=A; 90 G->vexs[1]=B; 91 G->vexs[2]=C; 92 G->vexs[3]=D; 93 G->vexs[4]=E; 94 G->vexs[5]=F; 95 G->vexs[6]=G; 96 G->vexs[7]=H; 97 G->vexs[8]=I; 98 99 100 for (i = 0; i < G->numVertexes; i++)/* 初始化圖 */ 101 { 102 for ( j = 0; j < G->numVertexes; j++) 103 { 104 G->arc[i][j]=0; 105 } 106 } 107 108 G->arc[0][1]=1; 109 G->arc[0][5]=1; 110 111 G->arc[1][2]=1; 112 G->arc[1][8]=1; 113 G->arc[1][6]=1; 114 115 G->arc[2][3]=1; 116 G->arc[2][8]=1; 117 118 G->arc[3][4]=1; 119 G->arc[3][7]=1; 120 G->arc[3][6]=1; 121 G->arc[3][8]=1; 122 123 G->arc[4][5]=1; 124 G->arc[4][7]=1; 125 126 G->arc[5][6]=1; 127 128 G->arc[6][7]=1; 129 130 131 for(i = 0; i < G->numVertexes; i++) 132 { 133 for(j = i; j < G->numVertexes; j++) 134 { 135 G->arc[j][i] =G->arc[i][j]; 136 } 137 } 138 139 } 140 141 Boolean visited[MAXVEX]; /* 訪問標誌的數組 */ 142 143 /* 鄰接矩陣的深度優先遞歸算法 */ 144 void DFS(MGraph G, int i) 145 { 146 int j; 147 visited[i] = TRUE; 148 printf("%c ", G.vexs[i]);/* 打印頂點,也可以其它操作 */ 149 for(j = 0; j < G.numVertexes; j++) 150 if(G.arc[i][j] == 1 && !visited[j]) 151 DFS(G, j);/* 對為訪問的鄰接頂點遞歸調用 */ 152 } 153 154 /* 鄰接矩陣的深度遍歷操作 */ 155 void DFSTraverse(MGraph G) 156 { 157 int i; 158 for(i = 0; i < G.numVertexes; i++) 159 visited[i] = FALSE; /* 初始所有頂點狀態都是未訪問過狀態 */ 160 for(i = 0; i < G.numVertexes; i++) 161 if(!visited[i]) /* 對未訪問過的頂點調用DFS,若是連通圖,只會執行一次 */ 162 DFS(G, i); 163 } 164 165 /* 鄰接矩陣的廣度遍歷算法 */ 166 void BFSTraverse(MGraph G) 167 { 168 int i, j; 169 Queue Q; 170 for(i = 0; i < G.numVertexes; i++) 171 visited[i] = FALSE; 172 InitQueue(&Q); /* 初始化一輔助用的隊列 */ 173 for(i = 0; i < G.numVertexes; i++) /* 對每一個頂點做循環 */ 174 { 175 if (!visited[i]) /* 若是未訪問過就處理 */ 176 { 177 visited[i]=TRUE; /* 設置當前頂點訪問過 */ 178 printf("%c ", G.vexs[i]);/* 打印頂點,也可以其它操作 */ 179 EnQueue(&Q,i); /* 將此頂點入隊列 */ 180 while(!QueueEmpty(Q)) /* 若當前隊列不為空 */ 181 { 182 DeQueue(&Q,&i); /* 將隊對元素出隊列,賦值給i */ 183 for(j=0;j<G.numVertexes;j++) 184 { 185 /* 判斷其它頂點若與當前頂點存在邊且未訪問過 */ 186 if(G.arc[i][j] == 1 && !visited[j]) 187 { 188 visited[j]=TRUE; /* 將找到的此頂點標記為已訪問 */ 189 printf("%c ", G.vexs[j]); /* 打印頂點 */ 190 EnQueue(&Q,j); /* 將找到的此頂點入隊列 */ 191 } 192 } 193 } 194 } 195 } 196 } 197 198 199 int main(void) 200 { 201 MGraph G; 202 CreateMGraph(&G); 203 printf("深度遍歷如下:\n"); 204 DFSTraverse(G); 205 printf("\n廣度遍歷如下:\n"); 206 BFSTraverse(G); 207 return 0; 208 }

運行效果如下:

技術分享

數據結構-深度遍歷和廣度遍歷(轉)