Bonstop算法模板(自创 + 整理)

本文深入探讨了图算法中的DFS、BFS和Dijkstra算法的实现细节,包括邻接矩阵和邻接表的不同应用方式。同时,文章还详细介绍了树的创建、遍历方法及其深度计算,为读者提供了丰富的代码示例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

目录

 

图:

DFS

BFS

Dijkstra


图:

DFS

const int MAXV = 1000;
const int INF = 1000000000;

//邻接矩阵
int n , G[MAXV][MAXV];
bool vis[MAXV] = {false};

void DFS(int u , depth){
	vis[u] = true;
	for(int i = 0 ; i < n ; i ++){
		if(vis[i] != false && G[u][i] != INF){
			DFS(i , depth + 1);
		}
	}
}

void DFSTrave(){
	for(int i = 0 ; i < u ; i ++){
		if(vis[i] == false){
			DFS(u);
		}
	}
}




//邻接矩阵写法
vector<int> v[MAXV];
bool vis[MAXV] = {false};

void DFS(int i , depth){
	vis[i] = true;
	for(int j = 0 ; j < n ; j ++){
		if(vis[i] == false && G[i][j] != INF){
			DFS(i , depth + 1);
		}
	}
}

void DFSTrave(){
	for(int i = 0 ; i < v.size() ; i ++){
		if(vis[i] == false){
			DFS(i , 0);
		}
	}
}

BFS

#include<vector>
#include<queue>
//邻接矩阵版本

void BFS(int u){
	queue<int> q;
	q.push(u);
	vis[u] = true;
	while(!q.empty()){
		int now = q.front();
		q.pop();
		for(int i = 0 ; i < n ; i ++){
			if(vis[i] == false && G[now][i] != INF){
				q.push(i);
				vis[i] = true;
			}
		}
	}
}

void BFSTrave(){
	for(int i = 0 ; i < n ; i ++){
		if(vis[u] == false){
			BFS(q);
		}
	}
} 


//邻接表
vector<int> v[MAXN];
bool vis[MAXN] = {false};

void BFS(int u){
	queue<int> q;
	q.push(u);
	vis[u] = true;
	while(!q.empty()){
		int now = q.front();
		q.pop();
		for(int i = 0 ; i < v[now].size() ; i ++){
			int k = v[now][i];
			if(vis[k] == false){
				q.push(k);
				vis[v] = true;
			}
		}
	}
}

void BFSTrave(){
	for(int i = 0 ; i < n ; i ++){
		if(vis[i] == false){
			BFS(i);
		}
	}
} 

Dijkstra

//用到的头文件 
#include<algorithm>

//初始化定义的数据 
int d[MAXV];
bool vis[MAXV] = {false};


void Dijkstra(int s){
	fill(d , d + MAXV , INF);
	d[s] = 0;
	for(int i = 0 ; i < n ; i ++){
		int u = -1 , MIN = INF;
		for(int j = 0 ; j < n ; j ++){
			if(vis[j] == false && d[j] < MIN){
				u = j;
				MIN = d[j];
			}
		} 
	
		if(u == -1)	return ;
	
		vis[u] = true;
	
		for(int j = 0 ; j < n ; j ++){
			if(vis[j] == false && G[u][j] != INF && d[u] + G[u][j] < d[j]){
				d[j] = d[u] + G[u][j];	//优化 
			}
		}
	}
}


//邻接表 
//用到的头文件
#include<vector>

struct node{
	int v , dis;
}; 

vector<node> v[MAXV];
int n , d[MAXV];
bool vis[MAXV] = {false};

void Dijkstra(int s){
	fill(d , d + MAXV , INF);
	d[s] = 0;
	
	for(int i = 0 ; i < v[s].size() ; i ++){
		int u = -1 , MIN = INF;
		for(int j = 0 ; j < n ; j ++){
			if(vis[j] == false && d[j] < MIN){
				u = j;
				MIN = d[j];
			}
		}
		
		if(u == -1)	return ;
		vis[u] = true;
		
		for(int j = 0 ; j < n ; j ++){
			int k = v[i][j];
			if(vis[k] == false && d[u] + v[u][j].dis < d[j]){
				d[j] = d[u] + v[u][j].dis;
			}
		} 
	}
} 

如何输出规定的最短路径?

//输出路径 
//初始化定义的数据 
int d[MAXV];
bool vis[MAXV] = {false};


void Dijkstra(int s){
	fill(d , d + MAXV , INF);
	d[s] = 0;
	for(int i = 0 ; i < n ; i ++){
		int u = -1 , MIN = INF;
		for(int j = 0 ; j < n ; j ++){
			if(vis[j] == false && d[j] < MIN){
				u = j;
				MIN = d[j];
			}
		} 
	
		if(u == -1)	return ;
	
		vis[u] = true;
	
		for(int j = 0 ; j < n ; j ++){
			if(vis[j] == false && G[u][j] != INF && d[u] + G[u][j] < d[j]){
				d[j] = d[u] + G[u][j];	
				
				//保存一个结点
				pre[j] = u; 
				
			}
		}
	}
}

void DFS(int s , int v){
	if(v == s){
		printf("%d\n" , s);
		return ;
	}
	DFS(s , pre[v]);
	printf("%d" , v); 
}

 

创建树

//建立一个结构体
struct node{
	int data , lchild , rchild;
}Node[MAXN];

//新建结点
int index = 0;
int newNode(int x){
	Node[index].data = x;
	Node[index].lchild = -1;
	Node[index].rchild = -1;
	return index ++;
} 

//插入结点
void insert(int &root , int x){
	if(root == -1){
		root = newNode(x);
		return ;
	}
	if(左结点){
		insert(Node[root].lchild , x);
	}
	else{
		insert(Node[root].rchild , x);
	}
} 

//建立二叉树
int create(int data[] , int n){
	int root = -1;
	for(int i = 0 ; i < n ; i ++){
		insert(root , data[i]);	
	}
	return root;
} 

树的遍历

#include<queue>

//前序遍历 
void preorder(int root){
	if(root == -1){
		return ;
	}
	printf("%d" , Node[root].data);
	preorder(Node[root].lchild);
	preorder(Node[root].rchild);
}

//中序遍历 
void inorder(int root){
	if(root == -1){
		return ;
	}
	inorder(Node[root].lchild);
	printf("%d" , Node[root].data);
	inorder(Node[root].rchild);
}

//后序遍历
void postorder(int root){
	if(root == -1){
		return ;
	}
	postorder(Node[root].lchild);
	postorder(Node[root].rchild);
	printf("%d" , Node[root].data);
} 

//层序遍历
void levelorder(int root){
	queue<int> q;
	q.push(root);
	while(!q.empty()){
		int now = q.front();
		q.pop();
		printf("%d" , Node[now].data);
		if(Node[now].lchild != -1)	q.push(Node[now].lchild);
		if(Node[now].rchild != -1)	q.push(Node[now].rchild);
	}
} 

树的遍历(树的深度问题,树的最深度问题,树的层数问题)


//保存路径 
void BFS(int index , int numNode , int sum){
	if(sum > S)	return ;
	if(sum == S){
		if(Node[index].child.size() != 0)	return ;
		for(int i = 0 ; i < numNode ; i ++){
			printf("%d" , Node[path[i]].weight);
			if(i < numNode - 1)	printf(" ");
			else printf("\n");
		}
		return ;
	}
	for(int i = 0 ; i < Node[index].child.size() ; i ++){
		int child = Node[index].child[i];
		path[numNode] = child;
		DFS(child , numNode + 1 , sum + Node[child].weight);
	}
}

DFS(0 , 1 , Node[0].weight);

//求树的深度 : DFS 
void DFS(int index , int depth){
	if(Node[index].size() == 0){
		return ;
	}
	for(int i = 0 ; i < Node[index].child.size() ; i ++){
		DFS(Node[index].child[i] , depth + 1);
	}
} 

DFS(1 , 0);

杂七杂八

#include<iostream>
#include<algorithm>
#include<unordered_map>
using namespace std;

int main(){
	string s = "abcd";
	
	//截取字符串 
	string t = s.substr(0 , 3);
	
	//c_str输出字符串 
	printf("%s" , s.c_str());	//	适用于输出
	
	//反转字符串 
	reverse(s.begin() , s.end()); 
	
	//long long 类型大约可以存储 10 ^ 19
	//int 类型可以存储大约 10 ^ 9左右的数据 
	
	printf("int = %d , long long = %lld" , sizeof(int) , sizeof(long long)); 
	
	//unordered_map : map的非排序版本
	unordered_map<int , int> um;
	um[2] = 3;
	um[3] = 4;
	um[5] = 3;
	for(auto it = um.begin() ; it != um.end() ; it ++){
		printf("%d %d\n" , it->first , it->second);
	}  
	return 0;
} 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值