以下介紹均已上圖爲依據,主要介紹無向圖。
1. 深度優先搜索
深度優先,即從圖中某一節A點開始訪問,然後訪問與之相連的一個節點C,再訪問與C相鄰的B節點。然後在隨機選擇一個未訪問的節點比如說是F,則接下來按照F->G->E->H的順序訪問,最後訪問D。
2. 廣度優先搜索
廣度優先,通從中一點A開始訪問,接下來,訪問所有與A相連的節點CDF,在訪問與C相連的所有節點B,繼續訪問與F相連的所有節點G,以此類推。
代碼
/*
* @Author: jobbofhe
* @Date: 2019-11-06 17:38:21
* @Last Modified by: Administrator
* @Last Modified time: 2019-11-11 18:13:56
*/
#include <stdio.h>
#include <stdlib.h>
#include <malloc.h>
#include <string.h>
#define IS_LETTER(c) ( (((c) >= 'a') && ((c) <= 'z')) || (((c) >= 'A') && ((c) <= 'Z')) )
#define LENGTH(c) (sizeof(c)/(sizeof(c[0])))
#define MAX_VERTEX (200)
// 臨接矩陣結構體
typedef struct GRAPH
{
int vertex_number;
int edge_number;
char vertex[MAX_VERTEX];
int matrix[MAX_VERTEX][MAX_VERTEX];
}Graph, *P_Graph;
int get_position(Graph graph, char ch)
{
for (int i = 0; i < graph.vertex_number; ++i)
{
if (graph.vertex[i] == ch)
{
return i;
}
}
return -1;
}
/*
* 創建圖(用已提供的圖數據)
*/
Graph* create_graph_2(char *vertex, char edges[][2], int vlen, int elen)
{
int i, p1, p2;
Graph* pG;
if ((pG=(Graph*)malloc(sizeof(Graph))) == NULL )
return NULL;
memset(pG, 0, sizeof(Graph));
// 初始化"頂點數"和"邊數"
pG->vertex_number = vlen;
pG->edge_number = elen;
printf("頂點數量: %d 邊數 :%d\n", vlen, elen);
// 初始化"頂點"
for (i = 0; i < pG->vertex_number; i++)
{
pG->vertex[i] = vertex[i];
}
// 初始化"邊"
for (i = 0; i < pG->edge_number; i++)
{
// 讀取邊的起始頂點和結束頂點
p1 = get_position(*pG, edges[i][0]);
p2 = get_position(*pG, edges[i][1]);
// 如果是無向圖,那麼兩個方向都設爲1
// 如果是有向圖,則 pG->matrix[p1][p2] = 1;
pG->matrix[p1][p2] = 1;
pG->matrix[p2][p1] = 1;
}
return pG;
}
void print_graph(Graph graph)
{
printf("頂點數量: %d\n", graph.vertex_number);
for (int i = 0; i < graph.vertex_number; ++i)
{
for (int j = 0; j < graph.vertex_number; ++j)
{
printf("%d ", graph.matrix[i][j]);
}
printf("\n");
}
}
/**
* 獲取第一個臨接點的索引
* @param graph [description]
* @param index_first [description]
* @return [description]
*/
int get_vertex_first_index(Graph graph, int index_first)
{
if (index_first < 0 || index_first > (graph.vertex_number-1))
{
return -1;
}
for (int i = 0; i < graph.vertex_number; ++i)
{
// 如果臨接矩陣 中頂點 index_vex的連接點 存在,則返回鄰接點的索引
if (graph.matrix[index_first][i] == 1)
{
return i;
}
}
return -1;
}
/**
* 獲取下一個臨接點的索引
* @param graph [description]
* @param index_first[description]
* @param index_next [description]
* @return [description]
*/
int get_vertex_next_index(Graph graph, int index_first, int index_next)
{
if (index_first < 0 || index_first > (graph.vertex_number-1)
|| index_next < 0 || index_next >(graph.vertex_number-1))
{
return -1;
}
for (int i = index_next+1; i < graph.vertex_number; ++i)
{
if (graph.matrix[index_first][i] == 1)
{
return i;
}
}
}
void DFS(Graph graph, int index, int *flag_visited)
{
flag_visited[index] = 1;
printf("%c ", graph.vertex[index]);
int i = 0;
// 遍歷該頂點的所有鄰接點,如果訪問數組標記位爲0,則繼續訪問
for (i = get_vertex_first_index(graph, index); i >= 0; i = get_vertex_next_index(graph, index, i))
{
if (flag_visited[i] == 0)
{
DFS(graph, i, flag_visited);
}
}
}
/**
* 深度優先搜索遍歷圖
* @param graph [graph]
*/
void deep_first_search(Graph graph)
{
// 節點被訪問標記
int flag_visited[MAX_VERTEX];
for (int i = 0; i < graph.vertex_number; ++i)
{
// 訪問之前所有頂點被訪問標記置爲0
flag_visited[i] = 0;
}
printf("------------ DFS -------------\n");
for (int i = 0; i < graph.vertex_number; ++i)
{
if (flag_visited[i] == 0)
{
DFS(graph, i, flag_visited);
}
}
printf("\n");
}
/**
* 廣度優先遍歷圖
*/
void breadth_first_search(Graph graph)
{
int tmp_array[MAX_VERTEX];
// 節點被訪問標記
int flag_visited[MAX_VERTEX];
for (int i = 0; i < graph.vertex_number; ++i)
{
// 訪問之前所有頂點被訪問標記置爲0
flag_visited[i] = 0;
}
printf("------------ BFS -------------\n");
int head = 0;
int tail = 0;
for (int i = 0; i < graph.vertex_number; ++i)
{
if (flag_visited[i] == 0)
{
flag_visited[i] = 1;
printf("%c ", graph.vertex[i]);
tmp_array[tail++] = i; // 已經訪問過的寫入臨時數組
}
while(head != tail)
{
int j = tmp_array[head++]; // 將已經訪問過的節點取出來
for (int k = get_vertex_first_index(graph, j); k > 0; k = get_vertex_next_index(graph, j, k))
{
if (flag_visited[k] == 0)
{
flag_visited[k] = 1;
printf("%c ", graph.vertex[k]);
tmp_array[tail++] = k;
}
}
}
}
printf("\n");
}
int main(int argc, char const *argv[])
{
char vertex[] = {'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H'};
char edges[][2] = {
{'A', 'C'},
{'A', 'D'},
{'A', 'F'},
{'B', 'C'},
{'C', 'D'},
{'F', 'G'},
{'G', 'E'},
{'E', 'H'}};
Graph* p_graph_2 = create_graph_2(vertex, edges, LENGTH(vertex), LENGTH(edges));
print_graph(*p_graph_2);
deep_first_search(*p_graph_2);
breadth_first_search(*p_graph_2);
return 0;
}