图的遍历记(深度和广度优先搜索—BFS&&DFS)的笔记

图的最基本的两种遍历方法,参考了算法导论的两个图例。

最值得说的是:

广度优先搜索(BFS)跟树的层次遍历比较像 用了队列(Queue)来作为临时储存的媒介。

深度优先搜索(DFS)跟输的前序遍历比较像——>(preoder traversal)。

先是广度优先搜索的图例:

《图的遍历记(深度和广度优先搜索—BFS&&DFS)的笔记》

然后上代码 以后补充w:

先是链表形式的:

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
typedef struct doubleLinkList* DL;
typedef struct queue* Q;
Q Qfront = NULL, Qrear = NULL;

struct doubleLinkList{
	int data;
	DL prev;
	DL next;
};

typedef struct queue{
	int data;
	Q next;
};

DL DLinsert(int data, DL head){
	DL newPtr = (DL)malloc(sizeof(doubleLinkList));
	newPtr->data = data;
	if (head == NULL){
		newPtr->prev = NULL;
		newPtr->next = NULL;
		head = newPtr;
	}
	else{
		newPtr->next = head;
		head->prev = newPtr;
		head = newPtr;
	}
	return head;
}

bool isEmpty(){
	if (!Qfront&&!Qrear) return true;
	else return false;
}

void enqueue(int data){
	Q newPtr = (Q)malloc(sizeof(queue));
	newPtr->data = data;
	if (isEmpty()){
		Qfront = Qrear = newPtr;
		newPtr->next = NULL;
	}
	else{
		Qrear->next = newPtr;
		Qrear = newPtr;
		Qrear->next = NULL;
	}
}

int dequeue(){
	int d;
	if (Qfront == NULL){
		Qrear = Qfront;
		printf("queue is already empty!\n\n");
		exit(0);
	}
	Q temp = Qfront;
	d = temp->data;
	Qfront = Qfront->next;
	if (Qrear == temp)Qrear = NULL;
	free(temp);
	return d;
}

int main(){
	int n = 0, u = 0, temp = 0;
	int * dis;
	DL* arr;
	DL start;
	
	printf("enter the number of vertex:");
	scanf("%d%*c", &n);

	dis = (int*)calloc(n, sizeof(int));
	arr = (DL*)calloc(n, sizeof(DL));
	
	for (int i = 0; i<n; i++){
		printf("enter the vertex through the node %d (-1 to end) :", i);
		while (scanf("%d", &temp) && temp != -1){
			arr[i] = DLinsert(temp, arr[i]);
		}
		printf("\n");
	}
	printf("enter the source node:");
	scanf("%d", &temp);
	printf("\n");

	enqueue(temp);
	while (Qfront != NULL){
		u = dequeue();
		start = arr[u];
		while (start != NULL){
			if (dis[start->data] == 0 && start->data != temp){
				dis[start->data] = dis[u] + 1;
				enqueue(start->data);
			}
			start = start->next;

		}

	}
	for (int i = 0; i <n; i++){
		printf(" %d: %d\n", i, dis[i]);
	}

	return 0;
}

output:

《图的遍历记(深度和广度优先搜索—BFS&&DFS)的笔记》

接着是矩阵形式的:

#include<stdio.h>
#include<stdlib.h>
#include<string.h>

typedef struct queue* Q;
Q Qfront = NULL, Qrear = NULL;

typedef struct queue{
	int data;
	Q next;
};

bool isEmpty(){
	if (!Qfront&&!Qrear) return true;
	else return false;
}

void enqueue(int data){
	Q newPtr = (Q)malloc(sizeof(queue));
	newPtr->data = data;
	if (isEmpty()){
		Qfront = Qrear = newPtr;
		newPtr->next = NULL;
	}
	else{
		Qrear->next = newPtr;
		Qrear = newPtr;
		Qrear->next = NULL;
	}
}

int dequeue(){
	int d;
	if (Qfront == NULL){
		Qrear = Qfront;
		printf("queue is already empty!\n\n");
		exit(0);
	}
	Q temp = Qfront;
	d = temp->data;
	Qfront = Qfront->next;
	if (Qrear == temp)Qrear = NULL;
	free(temp);
	return d;
}

int main(){
	int n = 0, u = 0, temp = 0;
	int** map;
	int*dis;

	printf("enter the number of vertex:");
	scanf("%d%*c", &n);

	map = (int**)malloc(n*sizeof(int*));
	for (int i = 0; i < n; i++) {
		*(map + i) = (int*)malloc(n*sizeof(int));
		memset(*(map + i), 0, sizeof(int)*n);
	}

	dis = (int*)malloc(n*sizeof(int));
	memset(dis, 0, n*sizeof(int));

	for (int i = 0; i<n; i++){
		printf("enter the vertex through the node %d (-1 to end) :", i);
		while (scanf("%d", &temp) && temp != -1){
			map[i][temp] = 1;
		}
		printf("\n");
	}
	printf("enter the source node:");
	scanf("%d", &temp);
	printf("\n");

	enqueue(temp);
	while (Qfront != NULL){
		u = dequeue();
		for (int i = 0; i<n; i++){
			if (map[u][i] == 1 && i != temp&&dis[i] == 0){
				dis[i] = dis[u] + 1;
				enqueue(i);
			}

		}
	}

	for (int i = 0; i <n; i++){

		for (int j = 0; j<n; j++)printf("%d ", map[i][j]);
		printf("\n");
	}
	printf("\ndis: ");
	for (int i = 0; i < n; i++) printf("%d", dis[i]);
	printf("\n\n");
	return 0;
}

矩阵形式的output:

《图的遍历记(深度和广度优先搜索—BFS&&DFS)的笔记》

下面是深度优先搜索:

先上图例:

《图的遍历记(深度和广度优先搜索—BFS&&DFS)的笔记》

首先是链表形式的:

#include<stdio.h>
#include<stdlib.h>
#include<string.h>

typedef struct doubleLinkList* DL;
typedef struct distime* dt;

int time = 0;
dt dis;
DL* arr;

struct distime{
	int start = 0;
	int end;
};


struct doubleLinkList{
	int data;
	DL prev;
	DL next;
};


DL DLinsert(int data, DL head){
	DL newPtr = (DL)malloc(sizeof(doubleLinkList));
	newPtr->data = data;
	if (head == NULL){
		newPtr->prev = NULL;
		newPtr->next = NULL;
		head = newPtr;
	}
	else{
		newPtr->next = head;
		head->prev = newPtr;
		head = newPtr;
	}
	return head;
}


void DFS(int i){
	DL ptr;
	time = time + 1;
	dis[i].start = time;
	ptr = arr[i];
	while (ptr != NULL){
		if (dis[ptr->data].start == 0)DFS(ptr->data);
		ptr = ptr->next;
	}
	time = time + 1;
	dis[i].end = time;
}


int main(){
	
	int n = 0,temp = 0;
	DL ptr;

	printf("enter the number of vertex:");
	scanf("%d%*c", &n);

	dis = (dt)calloc(n, sizeof(distime));
	arr = (DL*)calloc(n, sizeof(DL));
	
	for (int i = 0; i<n; i++){
		printf("enter the vertex through the node %d (-1 to end) :", i);
		while (scanf("%d", &temp) && temp != -1){
			arr[i] = DLinsert(temp, arr[i]);
		}
		printf("\n");
	}

	for (int i = 0; i<n; i++){
		if (dis[i].start == 0)DFS(i);
	}

	for (int i = 0; i<n; i++){
		printf("S:%d F:%d\n", dis[i].start, dis[i].end);
	}

	return 0;
}

链表形式的output(路径与图例所示是不同的 但是结果应该是对的):

《图的遍历记(深度和广度优先搜索—BFS&&DFS)的笔记》

最后是 深度优先搜索的矩阵形式:

#include<stdio.h>
#include<stdlib.h>
#include<string.h>

typedef struct distime* dt;

int time = 0, n = 0;
dt dis;
int** map;

struct distime{
	int start = 0;
	int end;
};

void DFS(int u){

	time = time + 1;
	dis[u].start = time;

	for (int i = 0; i<n; i++){
		if (dis[i].start == 0 && map[u][i] == 1)DFS(i);
	}
	time = time + 1;
	dis[u].end = time;
}


int main(){

	int temp = 0;

	printf("enter the number of vertex:");
	scanf("%d%*c", &n);

	dis = (dt)calloc(n, sizeof(distime));
	map = (int**)malloc(n*sizeof(int*));

	for (int i = 0; i < n; i++) {
		*(map + i) = (int*)malloc(n*sizeof(int));
		memset(*(map + i), 0, sizeof(int)*n);
	}

	for (int i = 0; i<n; i++){
		printf("enter the vertex through the node %d (-1 to end) :", i);
		while (scanf("%d", &temp) && temp != -1){
			map[i][temp] = 1;
		}
		printf("\n");
	}

	for (int i = 0; i<n; i++){
		if (dis[i].start == 0)DFS(i);
	}

	for (int i = 0; i <n; i++){
		for (int j = 0; j<n; j++)printf("%d ", map[i][j]);
		printf("\n");
	}
	printf("\n");
	for (int i = 0; i<n; i++){
		printf("S:%d F:%d\n", dis[i].start, dis[i].end);
	}

	return 0;
}

深度搜索矩阵形式的output(这回路径跟图例是完全一直的):

《图的遍历记(深度和广度优先搜索—BFS&&DFS)的笔记》

    原文作者:数据结构之图
    原文地址: https://blog.csdn.net/loppolloppol/article/details/17787137
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞