破“图”式(一)

图的原理

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

图的表示

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

图的算法实现

在这里插入图片描述
邻接表结构的定义

#define MaxSize 1024 

typedef struct _EdgeNode {//与节点连接的边的定义 
	int adjvex; //邻接的顶点在数组中的下标 
	int weight; //权重 
	struct _EdgeNode *next; //下一条边 
}EdgeNode; 

typedef struct _VertexNode{//顶点节点 
	char data; //节点数据 
	struct _EdgeNode *first;//指向邻接第一条边 
}VertexNode, AdjList; 

typedef struct _AdjListGraph { 
	AdjList *adjlist; 
	int vex; //顶点数 
	int edge; //边数 
}AdjListGraph;

邻接表的初始化

/*图的初始化*/ 
bool visited[MaxSize]; //全局数组,用来记录节点是否已被访问

void Init(AdjListGraph &G){ 
	G.adjlist = new AdjList[MaxSize]; 
	G.edge = 0; 
	G.vex = 0; 
	
	//遍历的标志位
	for (int i = 0; i < MaxSize; i++) { 
		visited[i] = false; 
	}
}

邻接表的创建

/*图的创建*/ 
void Create(AdjListGraph &G){ 
	cout << "请输入该图的顶点数以及边数:" << endl; 
	cin>> G.vex >> G.edge; 
	cout<<"请输入相关顶点:"<< endl; 
	for(int i=0; i<G.vex; i++){ 
		cin >> G.adjlist[i].data; 
		G.adjlist[i].first = NULL; 
	}
	
	char v1=0, v2=0;//保存输入的顶点的字符 
	int i1, i2; //保存顶点在数组中的下标 
	cout<<"请输入想关联边的顶点:"<< endl; 
	for(int i=0; i<G.edge; i++){ 
		cin >>v1 >>v2; 
		i1 = Location(G, v1); 
		i2 = Location(G, v2); 
		
		if(i1!=-1 && i2!=-1){//寻找到位置 
			EdgeNode *temp = new EdgeNode; 
			temp->adjvex = i2; 
			temp->next = G.adjlist[i1].first; 
			G.adjlist[i1].first = temp; 
		} 
	} 
}

/*通过顶点对应的字符寻找顶点在图中的邻接点*/ 
int Location(AdjListGraph &G, char c){
	for(int i=0; i<G.vex; i++){ 
		if(G.adjlist[i].data == c) { 
			return i; 
		} 
	}
	return -1; 
}

邻接表的深度遍历
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

/*对图上的顶点进行深度遍历*/ 
void DFS(AdjListGraph &G,int v){ 
	int next = -1; 
	
	if(visited[v]) return; 
	cout<<G.adjlist[v].data<<" "; 
	visited[v] = true; //设置为已访问 
	EdgeNode *temp = G.adjlist[v].first; 
	
	while(temp){
		next = temp->adjvex; 
		temp = temp->next; 
		
		if(visited[next] == false){ 
			DFS(G, next); 
		} 
	} 
}


/*对所有顶点进行深度遍历*/ 
void DFS_Main(AdjListGraph &G){ 
	for(int i=0; i<G.vex; i++){ 
		if(visited[i] == false){ 
			DFS(G, i); 
		} 
	} 
}

在这里插入图片描述

/*对图上的顶点进行广度遍历*/ 
void BFS(AdjListGraph &G,int v) { 
	queue <int> q; 
	int cur; 
	int next; 
	q.push(v); 
	
	while (!q.empty()) { //队列非空 
		cur = q.front(); //取队头元素 
		if (visited[cur] == false) { //当前顶点还没有被访问 
			cout << G.adjlist[cur].data << " "; 
			visited[cur] = true; //设置为已访问 
		}
		q.pop(); //出队列 
		EdgeNode *tp = G.adjlist[cur].first; 
	
		while (tp != NULL) { 
			next = tp->adjvex; 
			tp = tp->next; 
			q.push(next); //将第一个邻接点入队 
		}
	} 
}

/*对所有顶点进行广度遍历*/ 
void BFS_Main(AdjListGraph &G) { 
	for (int i = 0; i < G.vex; i++) { 
		if (visited[i] == false) { 
			BFS(G,i); 
		} 
	} 
}

在这里插入图片描述

#include <iostream> 

using namespace std; 

#define MaxSize 1024 

typedef struct _EdgeNode {//与节点连接的边的定义 
	int adjvex; //邻接的顶点 
	int weight; //权重 
	struct _EdgeNode *next; //下一条边 
}EdgeNode; 

typedef struct _VertexNode{//顶点节点 
	char data; //节点数据 
	struct _EdgeNode *first;//指向邻接第一条边 
}VertexNode, AdjList; 

typedef struct _AdjListGraph { 
	AdjList *adjlist; 
	int vex; //顶点数 
	int edge; //边数 
}AdjListGraph;

bool visited[MaxSize]={0}; //全局数组,用来记录节点是否已被访问 

int Location(AdjListGraph &G, char c); 

/*图的初始化*/ 
void Init(AdjListGraph &G){ 
	G.adjlist = new AdjList[MaxSize]; 
	G.edge = 0; 
	G.vex = 0; 
	
	for (int i = 0; i < MaxSize; i++) { 
		visited[i] = false; 
	} 
}

/*图的创建*/ 
void Create(AdjListGraph &G){ 
	cout << "请输入该图的顶点数以及边数:" << endl; 
	cin>> G.vex >> G.edge; 
	cout<<"请输入相关顶点:"<< endl; 
	
	for(int i=0; i<G.vex; i++){ 
		cin >> G.adjlist[i].data; 
		G.adjlist[i].first = NULL; 
	}
	
	char v1 = 0, v2 = 0;//保存输入的顶点的字符 
	int i1, i2; //保存顶点在数组中的下标 
	int weight = 0; 
	cout<<"请输入想关联边的顶点及权重:"<< endl; 
	
	for(int i=0; i<G.edge; i++){ 
		cin >>v1 >>v2 >>weight; 
		i1 = Location(G, v1); 
		i2 = Location(G, v2); 
		
		if(i1!=-1 && i2!=-1){//寻找到位置 
			EdgeNode *temp = new EdgeNode; 
			temp->adjvex = i2; 
			temp->next = G.adjlist[i1].first; 
			temp->weight = weight; 
			G.adjlist[i1].first = temp; 
		}
	}
}


/*通过顶点对应的字符寻找顶点在图中的邻接点*/ 
int Location(AdjListGraph &G, char c){ 
	for(int i=0; i<G.vex; i++){ 
		if(G.adjlist[i].data == c) { 
			return i; 
		} 
	}
	return -1; 
}

int min_weights = 0x7FFFFFFF; //最大的整数 2 的 32 次方-1 
int steps = 0; 
int path[MaxSize] = {0};//保存走过的路径 
int shortest_path[MaxSize] = {0}; //保存最短的路径 

/*对图上的顶点进行深度遍历*/ 
void DFS(AdjListGraph &G,int start, int end, int weights){ 
	int cur = -1; 
	//if(visited[start]) return; 
	cur = start; 
	if(cur == end){//已找到终点,不用继续遍历 
	
		//打印所经过的所有路径 
		for (int i = 0; i < steps; i++){ 			
			cout<<G.adjlist[path[i]].data<<" "; //输出路径 
		}
		printf("\t\t 该路径对应的长度是:%d\n", weights);//输出对应路 径长度 
		//更新最小路径
		if (min_weights > weights) { 
			min_weights = weights; 
			memcpy(shortest_path, path, steps*sizeof(int)); 
		} 
	}
	
	visited[start] = true; //设置为已访问
	EdgeNode *temp = G.adjlist[start].first; 
	
	while(temp){ 
		int weight = temp->weight; 
		cur = temp->adjvex;
		 
		if(visited[cur] == false){ 
			visited[cur] = true; //标记城市 i 已经在路径中 
			path[steps++] = cur;//保存路径到 path 数组中 
			DFS(G, cur, end, weights + weight); 
			visited[cur] = false;// 之前一步探索完毕后,取消对城市 i 的 标记以便另一条路径选择顶点 
			path[--steps] = 0; 
		}
		temp = temp->next; 
	} 
}


int main(){ 
	AdjListGraph G; //初始化 
	Init(G); 
	//创建图 
	Create(G); 
	
	char start, end; 
	
	cout<<"请输入要查询的最短路径的起点和终点:"<<endl; 
	cin >>start >>end; 
	
	//求两点间的最短路径 
	DFS(G, Location(G, start), Location(G, end), 0); 
	
	cout<<"最小路径长度为:"<<min_weights<<endl; 
	cout<<"路径:"; 
	
	int i=0; 
	while(i<MaxSize && shortest_path[i]>0){ 
		cout<<G.adjlist[shortest_path[i]].data<<" "; 
		i++; 
	}
	cout<<endl; 
	system("pause"); 
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值