深度优先遍历类似于树的先序遍历。假设给定初态是图中所有顶点均未被访问过,从图中某一顶点vi出发遍历图中的定义如下:首先访问出发点vi,并将其访问标志置为1;然后,从vi出发点依次搜索vi的每个邻接点vj。如vj未被访问过,则以vj为新的出发点继续进行深度优先搜索。
广度优先遍历,类似于树的按层次遍历。设图G是连通的,且图G的初态是所有顶点均未被访问过。从图G的任一顶点vi出发按广度优先搜索遍历图的步骤是:访问vi后,依次访问与vi邻接的所有顶点w1,w2,w3......wn,再按w1,w2,w3......wn的顺序访问其中每个顶点的所有未被访问的邻接点,再按此顺序,依次访问它们所有未被访问的邻接点,以此类推,直到图中所有顶点均被访问过为止。
比如,以下面的图为例(包括不连通的顶点):
图中包括9个顶点,顶点序号为0~8,顶点信息为依次为字符 'a' ~ ' i',其中顶点8不与其他顶点相连通。
利用递归形式的深度优先遍历:
遍历结果:0->1->3->7->4->5->2->6 ->8 输出结果:a->b->d->h->e->f->c->g->i
利用非递归形式(栈)的深度优先遍历:
遍历结果:0->1->3->7->4->5->2->6 ->8 输出结果:a->b->d->h->e->f->c->g->i
利用广度优先遍历(队列):
遍历结果:0->1->2->3->4->5->6->7 ->8 输出结果:a->b->c->d->e->f->g->h->i
程序如下(有问题共同交流):
#include<iostream> #include<assert.h> #include<string> #define NUM 9 #define MAXSIZE 15 using namespace std; typedef struct graph { char vertexs[NUM]; int matrixs[NUM][NUM]; }; typedef struct stack { int dataNum[MAXSIZE]; int top; int stackSize; }; typedef struct queue { int dataArray[MAXSIZE]; int front; int rear; }; //直接创建图 void CreateGraph(graph * g); //深度优先遍历(递归形式)图中所有连通顶点,打印顶点信息 void DFS(graph* g, int i, int visit[NUM]); //深度优先遍历(递归形式)图中剩余其他顶点,打印顶点信息 void FinalDFS(graph* g, int visit[NUM]); //创建栈 void CreateStack(stack *s); //判断栈是否为空 int EmptyStack(stack *s); //将顶点序号入栈 void PushStack(stack *s, int k); //出栈,取栈顶元素 int PopStack(stack *s); //利用栈,深度优先遍历(非递归形式)图中每个顶点 void DFS_Stack(graph *g, int i, stack* s, int visit[NUM]); //利用栈,深度优先遍历(非递归形式)图中所有顶点 void FinalDFS_Stack(graph *g, stack* s, int visit[NUM]); //创建队列 void CreateQueue(queue *q); //判断队列是否为空 int EmptyQueue(queue *q); //入队,将顶点序号入队 void ENQUEUE(queue *q, int e); //出队,将队头元素出队 int DEQUEUE(queue *q); //利用队列,广度优先遍历图中和源点i相连通的所有顶点 void BFS_Queue(graph *g, int i, queue* q, int visit[NUM]); //利用队列,广度优先遍历图中所有顶点(包括不连通顶点) void FinalBFS_Queue(graph *g, queue* q, int visit[NUM]); int main() { graph g; CreateGraph(&g); int visit[NUM] = {0}; //利用深度优先搜索遍历(递归形式) printf("深度优先遍历(递归形式): "); FinalDFS(&g,visit); printf("\n"); //利用深度优先遍历(非递归形式:栈) printf("深度优先遍历(非递归形式 栈): "); int visit1[NUM] = { 0 }; stack s; CreateStack(&s); FinalDFS_Stack(&g, &s, visit1); printf("\n"); //利用广度优先遍历(队列) printf("广度优先遍历(队列): "); int visit2[NUM] = { 0 }; queue q; CreateQueue(&q); FinalBFS_Queue(&g, &q, visit2); printf("\n"); return 0; } //创建图 void CreateGraph(struct graph * g) { //默认9个顶点信息依次为字符"a b c d e f g h i" for (int i = 0; i < NUM; i++) { g->vertexs[i] = 'a'+i; } //直接创建图的邻接矩阵 g->matrixs[0][1] = 1; g->matrixs[0][2] = 1; g->matrixs[1][0] = 1; g->matrixs[1][3] = 1; g->matrixs[1][4] = 1; g->matrixs[2][0] = 1; g->matrixs[2][5] = 1; g->matrixs[2][6] = 1; g->matrixs[3][1] = 1; g->matrixs[3][7] = 1; g->matrixs[4][1] = 1; g->matrixs[4][7] = 1; g->matrixs[5][2] = 1; g->matrixs[5][7] = 1; g->matrixs[6][2] = 1; g->matrixs[6][7] = 1; g->matrixs[7][3] = 1; g->matrixs[7][4] = 1; g->matrixs[7][5] = 1; g->matrixs[7][6] = 1; } //深度优先遍历(递归形式)图中所有联通顶点,打印顶点信息 void DFS(graph* g, int i, int visit[NUM]) { //将访问到的顶点的标志位赋1 visit[i] = 1; //打印访问到的顶点信息 printf("%c ", g->vertexs[i]); for (int j = 0; j < NUM; j++) { if (g->matrixs[i][j]==1 && visit[j]==0) { DFS(g,j,visit); } } } //深度优先遍历(递归形式)图中所有顶点,打印顶点信息 void FinalDFS(graph* g, int visit[NUM]) { //遍历所有顶点 for (int m = 0; m < NUM; m++) { if (visit[m] == 0) { DFS(g, m, visit); } } } //创建栈 void CreateStack(stack *s) { //将栈置空 s->top = -1; s->stackSize = MAXSIZE; } //判断栈是否为空 int EmptyStack(stack *s) { if (s->top==-1) return 1; else return 0; } //将顶点序号入栈 void PushStack(stack *s, int k) { if (s->top == (s->stackSize-1)) { printf("overflow"); return; } else { s->top++; s->dataNum[s->top] = k; } } //出栈,取栈顶元素 int PopStack(stack *s) { if (EmptyStack(s)==1) { return -1; } else { int vexNum=s->dataNum[s->top]; s->top--; return vexNum; } } //利用栈,深度优先遍历(非递归形式)图中每个顶点 void DFS_Stack(graph *g, int i, stack* s, int visit[NUM]) { visit[i] = 1; //将第一个顶点入栈 PushStack(s,i); //打印第一个顶点信息 printf("%c ",g->vertexs[s->dataNum[s->top]]); while (s->top!=-1) { int x = s->dataNum[s->top]; int flag = 0; for (int j = 0; j < NUM;j++) { if (g->matrixs[x][j] == 1 && visit[j] == 0) { visit[j] = 1; PushStack(s,j); flag = 1; printf("%c ", g->vertexs[s->dataNum[s->top]]); break; } } if (flag==0) { PopStack(s); } } } //利用栈,深度优先遍历(非递归形式)图中所有顶点 void FinalDFS_Stack(graph *g, stack* s, int visit[NUM]) { //遍历所有顶点 for (int m = 0; m < NUM; m++) { if (visit[m] == 0) { DFS_Stack(g, m, s, visit); } } } //创建队列 void CreateQueue(queue *q) { q->front = q->rear = 0; } //判断队列是否为空 int EmptyQueue(queue *q) { if (q->front == q->rear) return 1; else return 0; } //入队,将顶点序号入队 void ENQUEUE(queue *q, int e) { if (q->rear-q->front==(MAXSIZE-1)) { printf("队满上溢"); return; } else { q->dataArray[q->rear] = e; q->rear++; } } //出队,将队头元素出队 int DEQUEUE(queue *q) { if (EmptyQueue(q)==1) { return -1; } else { int frontNum =q->dataArray[q->front]; q->front++; return frontNum; } } //利用队列,广度优先遍历图中和源点i相连通的所有顶点 void BFS_Queue(graph *g, int i, queue* q, int visit[NUM]) { visit[i] = 1; //将第一个顶点入队 ENQUEUE(q,i); //打印第一个顶点信息 //printf("%c ", q->dataArray[q->front]); while (EmptyQueue(q)!=1) { int k = DEQUEUE(q); printf("%c ", g->vertexs[k]); for (int j = 0; j < NUM;j++) { if (g->matrixs[k][j] == 1 && visit[j] == 0) { visit[j] = 1; ENQUEUE(q, j); } } } } //利用队列,广度优先遍历图中所有顶点(包括不连通顶点) void FinalBFS_Queue(graph *g, queue* q, int visit[NUM]) { //遍历所有顶点 for (int m = 0; m < NUM; m++) { if (visit[m] == 0) { BFS_Queue(g, m, q, visit); } } }
输出结果如下: