数据结构⑤ 图(存储&&遍历)

目录

定义和基本术语

存储

数组(邻接矩阵)存储法

原理

代码实现

优缺点

链表(邻接表)存储法

原理

代码实现

优缺点

前两者对比

十字链表(了解)

邻接多重表

​编辑

遍历 

DFS

原理

代码实现

效率分析

附加应用(数(强)连通分量)

BFS

原理

代码实现

效率分析

附加应用(数(强)连通分量)

两者比较


定义和基本术语

存储

数组(邻接矩阵)存储法

原理

顶点表Vexs + 邻接矩阵arcs

代码实现

#include<stdio.h>
#define MaxInt 32767
#define MVNum 100

typedef char VexType;
typedef int AcrType;
typedef struct{
	VexType vexs[MVNum];
	AcrType arcs[MVNum][MVNum];
	int vexnum , arcnum;
}AMGraph;

int LocateVex(AMGraph G , int v){
	for(int i = 0 ; i < G.vexnum ; i++){
		if(v == G.vexs[i])	return i;
	}
	return -1;
}

void CreateUDN(AMGraph &G){
	scanf("%d %d",&G.vexnum , &G.arcnum);
	for(int i = 0 ; i < G.vexnum ; i++){
		scanf("%c",&G.vexs[i]);
	}
	
	for(int i = 0 ; i < G.arcnum ; i++){
		for(int j = 0 ; j < G.arcnum ; j++){
			G.arcs[i][j] = MaxInt;
		}
	}
	
	for(int i = 0 ; i < G.arcnum ; i++){
		int v1 , v2 , w;
		scanf("%d %d %d",&v1,&v2,w);
		int m = LocateVex(G , v1);
		int n = LocateVex(G , v2);
		G.arcs[m][n] = w;
		G.arcs[n][m] = w;
	}
	
}
int main(){
	
	return 0;
}

无向图:

初始化邻接矩阵时,w均为0;

构造邻接矩阵时,w为1。

有向网:

不要对称过去!单向!

优缺点

链表(邻接表)存储法

原理

代码实现

#include<stdio.h>
#define VerTexType int
#define MVNum 100

typedef struct ArcNode{
	int adjvex;
	struct ArcNode* nextarc;
}ArcNode;

typedef struct VNode{
	VerTexType data;
	ArcNode* firstarc;
}VNode , AdjList[MVNum];

typedef struct{
	AdjList vertices;
	int vexnum , arcnum;
}ALGraph;

int LocateVex(ALGraph G , int v){
	for(int i = 0 ; i < G.vexnum ; i++){
		if(v == G.vertices[i].data)	return i;
	}
	return -1;
}

void CreateUDG(ALGraph &G){
	scanf("%d %d",&G.vexnum,&G.arcnum);
	for(int i = 0 ; i < G.vexnum ; i++){
		scanf("%d",&G.vertices[i].data);
		G.vertices[i].firstarc = NULL;
	}
	
	for(int i = 0 ; i <= G.arcnum ; i++){
		int v1 , v2;
		int m = LocateVex(G , v1);
		int n = LocateVex(G , v2);
		
		ArcNode* p1 = new ArcNode;
		p1->adjvex = n;
		p1->nextarc = G.vertices[m].firstarc;
		G.vertices[m].firstarc = p1;
		
		ArcNode* p2 = new ArcNode;
		p2->adjvex = m;
		p2->nextarc = G.vertices[n].firstarc;
		G.vertices[n].firstarc = p2;
	}
}

int main(){
	
	return 0;
}

优缺点

前两者对比

十字链表(了解)

邻接多重表

遍历 

DFS

原理

代码实现

#include<stdio.h>
#include<string.h>
#define MaxNum 100

typedef struct{
	int vex[MaxNum];
	int arc[MaxNum][MaxNum];
	int vexnum , arcnum;
}AMGraph;

int LocateVex(AMGraph G , int v1){
	for(int i = 0 ; i < G.vexnum ; i++){
		if(G.vex[i] == v1)	return i;
	}
	return -1;
}

void CreatUDN(AMGraph &G){
	scanf("%d %d",G.vexnum , G.arcnum);
	for(int i = 0 ; i < G.vexnum ; i++){
		scanf("%d",G.vex[i]);
	}
	
	memset(G.arc , '\0' , sizeof G.arc);
	for(int i = 0 ; i < G.arcnum ; i++){
		int v1 , v2 , w;
		scanf("%d %d %d",&v1,&v2,w);
		int m = LocateVex(G , v1);
		int n = LocateVex(G , v2);
		G.arc[m][n] = w;
		G.arc[n][m] = w;
	}
}

bool visit[MaxNum];

void DFS(AMGraph G , int v){
	visit[v] = true;
	for(int j = 0 ; j < G.vexnum ; j++){
		if(G.arc[v][j] != 0 && visit[j] != 1){
			DFS(G , j);
		}
	}
}

int main(){
	memset(visit , '\0' , sizeof visit);
	return 0;
}

效率分析

附加应用(数(强)连通分量)

非联通图:随便选一个当开始结点把它DFS完,再选一个没visit过的结点,把它DFS完……(以此类推)

∴ 这也是一种数连通分量的方法

BFS

原理

代码实现

#include<stdio.h>
#include<string.h>
#define MAXSIZE 100
#define MVNum 100

typedef struct{
	int* base;
	int front;
	int rear;
}SqQueue;

void InitQueue(SqQueue &Q){
	Q.base = new int[MAXSIZE];
	Q.front = Q.rear = 0;
}

void EnQueue(SqQueue &Q , int e){
	Q.base[Q.rear] = e;
	Q.rear = (Q.rear + 1) % MAXSIZE;
}

void DeQueue(SqQueue &Q , int &e){
	e = Q.base[Q.front];
	Q.front = (Q.front + 1) % MAXSIZE;
}

bool QueueEmpty(SqQueue Q){
	if(Q.front == Q.rear)	return true;
	return false;
}

typedef struct ArcNode{
	int adjvex;
	struct ArcNode* nextarc;
}ArcNode;

typedef struct VNode{
	int data;
	ArcNode* firstarc;
}VNode , AdjList[MVNum];

typedef struct ALGraph{
	AdjList vertices;
	int vexnum , arcnum;
}ALGraph;


int LocateVex(ALGraph G , int v){
	for(int i = 0 ; i < G.vexnum ; i++){
		if(v == G.vertices[i].data)	return i;
	}
	return -1;
}

void CreatUDG(ALGraph &G){
	scanf("%d %d",G.vexnum,G.arcnum);
	for(int i = 0 ; i < G.vexnum ; i++){
		scanf("%d",G.vertices[i].data);
		G.vertices[i].firstarc = NULL;
	}
	for(int i = 0 ; i < G.arcnum ; i++){
		int v1 , v2;
		scanf("%d %d",&v1,&v2);
		int m = LocateVex(G , v1);
		int n = LocateVex(G , v2);
		ArcNode* p1 = new ArcNode;
		p1->adjvex = m;
		p1->nextarc = G.vertices[m].firstarc;
		G.vertices[m].firstarc = p1;
		ArcNode* p2 = new ArcNode;
		p2->adjvex = n;
		p2->nextarc = G.vertices[n].firstarc;
		G.vertices[n].firstarc = p2;
	}
}

int visit[MAXSIZE];

void BFS(ALGraph G , int v){
	visit[v] = true;
	SqQueue Q;
	InitQueue(Q);
	EnQueue(Q , v);
	while(QueueEmpty(Q) != true){
		int u;
		DeQueue(Q , u);
		for(int w = FirstAdjVex(G , u) ; w > 0 ; w = NextAdjVex(G , u , w)){
			if(visit[w] == 0 ){
				visit[w] = true;
				EnQueue(Q , w);
			}
		}
	}
}

int main(){
	memset(visit , '\0' , sizeof visit);
	return 0;
}

队列还有图都是小蒟蒻手敲的,语法没错,欢迎佬指正

ps:FirstAdjVex 和 NextAdjVex 还没写,2023年2月2日更新

(2023年3月12日评:可恶,忘记写了,so 写了一个代替这两个函数的,用了指针p)

void BFS (ALGraph G, int v) {
	visited[v] = true;
	queue<int> q1;
	q1.push(v);
	while (q1.empty() != false) {
		int u = q1.front();
		q1.pop();
		ArcNode *p = G.vertices[u].firstarc;
		for (int i = G.vertices[u].firstarc -> adjvex; i >= 0;) {
			if (visited[i] == false) {
				visited[i] = true;
				q1.push(i);
			}
			p = p -> nextarc;
			i = p -> adjvex;
		}
	}
}

效率分析

附加应用(数(强)连通分量)

非联通图:随便选一个当开始结点把它DFS完,再选一个没visit过的结点,把它DFS完……(以此类推)

∴ 这也是一种数连通分量的方法

两者比较

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值