BFS+DFS非递归的实现代码

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接: https://blog.csdn.net/weixin_42568655/article/details/102240401

前言

为什么要使用C语言

因为c语言中基本没有数据结构, 所有的数据结构都需要自己来定义, 看一个人有没有真正的理解这个算法, 那么用C语言能写出来就算是真正的明白了这个算法的过程, 所以c语言是检验技术的一个有力的方法

为什么要弄明白这些算法

我的老师王老师说过, 会底层的才是人才, 应用都是最基础的, 都是小儿科 核心思想在别人那里想给你用就给你用, 不给你用你也没有办法.

简要说明

BFS和DFS是数据结构中图的遍历中使用的算法, 跟二叉树的遍历有着异曲同工之妙.

BFS

BFS, Breadth First Search, 广度优先遍历, 遍历思路为: 从最开始遍历的结点开始, 按顺序一次找到所有的距离当前结点最近的结点, 知道所有的结点都被遍历完成.

这样的话我们可以用一个队列的数据结构来实现这个BFS遍历方法

队列 -> BFS

  1. 将开始访问的结点放入队头中
  2. 将队头的临接结点放入队列中
  3. 开始的结点pop弹出
  4. 重复2, 3直到队列为空
  5. 注意: 每次只pop弹出一个元素, 放入所有的邻接结点, 队列中的元素不重复(逻辑)

DFS

DFS, Deepth First Search, 深度优先遍历, 遍历思路为: 从最开始遍历的结点, 一条路走到黑, 知道五路可走, 再返回一个有路的结点, 最新的路(也就是访问未访问的结点), 直到所有的结点都被访问/(遍历)过

与BFS相似, 我们可以用一个栈的数据结构来实现这个DFS算法

栈 -> DFS

  1. 将开始访问的结点的放入栈中
  2. 将栈中的一个元素pop弹出,
  3. 当前弹出的元素的邻接结点全部放入栈中
  4. 重复2, 3, 直到栈为空
  5. 注意: 每次在栈中只pop一个元素, 放入的不一定是一个, 栈中的元素不重复(逻辑).

代码实现

测试图

在这里插入图片描述

代码+测试主方法

/*
***********************************************************************
******************** Breadth First Search and *************************
******************** Deepth First Search ******************************
******************** Author : Master_Joe Guangtong*********************
***********************************************************************
*/

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

// set length of stack or queue
#define MAX_SIZE 32

// Stack data structure
typedef struct stack {
	int length;
	char datas[MAX_SIZE];
} Stack;

// Queue data structure
typedef struct queue {
	int front;
	int rear;
	char datas[MAX_SIZE];
} Queue;

// Graph node data structure
typedef struct node {
	char data;
	struct node* next;
} Node; 

// Graph data structure
typedef struct graph {
	int numNodes;
	// adjacency list
	Node* adjLists[128];
	int visited[128];
} Graph;

/**
 * Create a stack with no element
 */
Stack* create_stack() {
	return malloc(sizeof(Stack));
}

/**
 * Create a queue with no elment
 */
Queue* create_queue() {
	return malloc(sizeof(Queue));
}

/**
 * Create an node with a element
 */
Node* create_node(char value) {
	Node* node = malloc(sizeof(Node));
	node -> data = value;
	node -> next = NULL;
	return node;
}

/**
 * Create Graph with number of vertices
 * @param n number of vertices
 */
Graph* create_graph(int n) {
	Graph* graph = malloc(sizeof(Graph));
	graph -> numNodes = n;
/*
	It is not necessary
	graph -> adjLists = malloc(n * sizeof(Node));
	graph -> visited = malloc(n * sizeof(Node));

	int i;
	for (i = 0; i < n; i++) {
		// No Nodes, no visiting
		graph -> adjLists[i] = NULL;
		graph -> visited[i] = 0;
	}
*/	
	return graph;
}

/**
 * Add edges to a graph
 * @param graph the specified graph to add
 * @param start start node in an edge
 * @param end end node in an edge
 */
void add_edge(Graph* graph, char start, char end) {
	// Add edge from start to end 
	Node* node = create_node(end);
	node -> next = graph -> adjLists[start];
	graph -> adjLists[start] = node;

	// Add edge from end to start
	node = create_node(start);
	node -> next = graph -> adjLists[end];
	graph -> adjLists[end] = node;
}

/**
 * insert a value into a Stack
 * @param stack which stack you will insert into
 * @param value what you want to insert
 */
void push_s(Stack* stack, char value) {
	if (stack -> length != MAX_SIZE) {
		stack -> datas[stack -> length++] = value;
	} else {
		printf("stack overflow!!");
	}
}

/**
 * decide if a queue is full
 * @return {@code 1} is full <br>
 * 		   {@code 0} is not full
 */
int is_full_q(Queue* queue) {
	if (queue -> rear == MAX_SIZE - 1) {
		return 1;
	} 
	else {
		return 0;
	}
}

/**
 * decide if a queue is empty
 * @return {@code 1} is empty
 *         {@code 0} is not empty
 */
int is_empty_q(Queue* queue) {
	if (queue -> front == queue -> rear) {
		return 1;
	}
	else {
		return 0;
	}
}

/**
 * decide if a stack is empty
 * @return {@code 1} is empty
 *         {@code 0} is not empty
 */
int is_empty_s(Stack* stack) {
	if (stack -> length == 0) {
		return 1;
	}
	else {
		return 0;
	}
}

/**
 * insert a value into a Queue
 * @param queue which queue you will insert into
 * @param value what you will insert
 */
void push_q(Queue* queue, char value) {
	if (!is_full_q(queue)) {
		queue -> datas[queue -> rear++] = value;
	} else {
		printf("Queue is full");
	}
}

/**
 * pop element from first
 * @param queue where you will pop
 * @return the first element 
 */
char pop_q(Queue* queue) {
	if (queue -> front != queue -> rear) {
		return queue -> datas[queue -> front++];
	} else {
		return -1;
	}
}

/**
 * pop the end element of a Stack
 * @param stack you will get its last element
 * @return the last element of {@code stakc}
 */
char pop_s(Stack* stack) {
	if (stack -> length != 0) {
		return stack -> datas[--stack -> length];
	} else {
		return -1;
	}
}

/** 
 * Breadth first search
 * @param graph specified graph made bfs
 * @param start start vertex in bfs
 */
void bfs(Graph* graph, char start) {
	Queue* queue = create_queue();
	graph -> visited[start] = 1;
	push_q(queue, start);

	while(!is_empty_q(queue)) {
		char current = pop_q(queue);
		printf("%c\n", current);
		Node* temp = graph -> adjLists[current];

		while (temp != NULL) {
			// Traverse the whole graph
			char adjD = temp -> data;
			if (graph -> visited[adjD] == 0) {
				graph -> visited[adjD] = 1;
				push_q(queue, adjD);
			}
			temp = temp -> next;
		}
	}
}

/** 
 * Deepth first search
 * @param graph specified graph made bfs
 * @param start start vertex in bfs
 */
void dfs(Graph* graph, char start) {
	// Queue* queue = create_queue();
	Stack* stack = create_stack();
	graph -> visited[start] = 1;
	push_s(stack, start);

	while(!is_empty_s(stack)) {
		char current = pop_s(stack);
		printf("%c\n", current);
		Node* temp = graph -> adjLists[current];

		while (temp != NULL) {
			// Traverse the whole graph
			int adjD = temp -> data;
			if (graph -> visited[adjD] == 0) {
				graph -> visited[adjD] = 1;
				push_s(stack, adjD);
			}
			temp = temp -> next;
		}
	}
}

/*
	
*/
int main() {
	Graph* graph = create_graph(5);
	add_edge(graph, 'A', 'B');
	add_edge(graph, 'A', 'C');
	add_edge(graph, 'B', 'C');
	add_edge(graph, 'B', 'D');
	add_edge(graph, 'C', 'D');
	add_edge(graph, 'C', 'E');
	add_edge(graph, 'D', 'E');
	add_edge(graph, 'D', 'F');
	bfs(graph, 'B');
	return 0;
}

猜你喜欢

转载自blog.csdn.net/weixin_42568655/article/details/102240401