图的表示与遍历(c)

图的表示与遍历

邻接矩阵,邻接表以及深度优先搜索,广度优先搜索
1.邻接矩阵

typedef struct Graph* graph;
//邻接矩阵结构表示
struct Graph {
	//datatype data[maxsize];//当顶点具有其他意义时
	int dot;//顶点数
	int line;//边数
	int map[maxsize][maxsize];
};
//所插入的边结构表示
typedef struct linenode* edge;
struct linenode {
	int dot1, dot2;
	//int wight;//当定义有权图时使用,用来存储权
};
//初始化具有n个节点没有边的图
graph create(int dotnum) {
	graph g;
	int i, j;
	g = (graph)malloc(sizeof(struct Graph));
	g->dot = dotnum;
	g->line = 0;
	for (i = 0; i < g->dot; i++) {
		for (j = 0; j < g->dot; j++) {
			g->map[i][j] = 0;//当两个点的边不存在时设为0
		}
	}
	return g;
}
//插入边数
void insert(graph g,edge e){
	//g->map[e->dot1][e->dot2] = e->wight;//有权重时
	//g->map[e->dot2][e->dot1] = e->wight;//当为无向图时需定义两边
	g->map[e->dot1][e->dot2] = 1;//无权重时
	g->map[e->dot2][e->dot1] = 1;
}
//建造图
graph bulidgraph() {
	int dotnum;
	printf("请输入所建图所需的点数");
	scanf_s("%d", &dotnum);//读入所建图的点数
	graph g = create(dotnum);
	printf("请输入所建图的边数");
	scanf_s("%d", &g->line);//读入边数
	if (g->line != 0) {
		edge e=(edge)malloc(sizeof(struct linenode));
		for (int i = 0; i < g->line; i++) {
			//printf("添加边,请输入第一个点,第二个点,以及权重");
			//scanf_s("%d%d%d", &e->dot1, &e->dot2, &e->wight);
			printf("添加边,请输入第一个点,第二个点");
			scanf_s("%d%d", &e->dot1, &e->dot2);
			insert(g, e);
		}
	}
	return g;
}

邻接表,主要用于稀疏矩阵

//所插入的边结构表示
typedef struct linenode* edge;
struct linenode {
	int dot1, dot2;
	//int wight;//当定义有权图时使用,用来存储权
};
//链表结构,每个节点包含该点的位置以及一个指针
typedef struct ln* linenode;
struct ln {
	int dot;//该弧所指向顶点的位置
	//int weight;//有权图
	linenode next;//指向下一条弧的指针
};
//邻接表结构,用存储链表的数组实现,包含第一个节点的信息
typedef struct Vnode {
	linenode firstedge;//第一条依附该顶点的弧指针
	//data data;//若顶点还需要存储其他数据
}Adjlist[maxsize];
//图的邻接表表示结构
typedef struct AList* list;
struct AList {
	int dots;//图所含点数
	int lines;//图所含边数
	Adjlist G;//邻接表
};
//初始化邻接表
list createlist(int dotnum) {
	 list g;
	 g = (list)malloc(sizeof(struct AList));
	 g->dots = dotnum;
	 g->lines = 0;
	 for (int i = 0; i < dotnum; i++) {
		 g->G[i].firstedge = NULL;//将所有链表都设为空
	}
	 return g;
}
void insertlist(list g, edge e) {
	//有向图
	//linenode l=(linenode)malloc(sizeof(struct Vnode));
	//l->dot = e->dot2;
	//l->next = g->G[e->dot1].firstedge;
	//g->G[e->dot1].firstedge = l;
	//g->G[e->dot1].firstedge->weight=weight//若有权重
	//无向图
	linenode l = (linenode)malloc(sizeof(struct Vnode));
	l->dot = e->dot2;
	l->next = g->G[e->dot1].firstedge;
	g->G[e->dot1].firstedge = l;//插入在第一个节点处
	l = (linenode)malloc(sizeof(struct Vnode));
	l->dot = e->dot1;
	l->next = g->G[e->dot2].firstedge;
	g->G[e->dot2].firstedge = l;
}
list buildlist() {
	
	printf("请输入图所含的点数");
	int dotnum;
	edge e=(edge)malloc(sizeof(struct linenode));
	scanf_s("%d", &dotnum);
	list l = createlist(dotnum);
	printf("请输入图所含的边数");
	scanf_s("%d",&l->lines);
	if (l->lines != 0) {
		for (int i = 0; i < l->lines; i++) {
			printf("请输入第一个点,第二个点");
			scanf_s("%d%d", &e->dot1, &e->dot2);
			insertlist(l, e);
		}
	}
	return l;
}

3.图的遍历
1.DFS,深度优先搜索
邻接表的深度优先搜索

邻接表的深度优先搜索
void DFS(list l, int x,int* visited) {
	printf("正在遍历第%d个节点",x);

	linenode w = l->G[x].firstedge;
	visited[x] = 1;
	while (w) {
		if (!visited[w->dot]) DFS(l, w->dot,visited);
		w = w->next;
	}
}
void DFStraverse(list l) {//邻接表所存储的图,从x为出发点对图进行DFS深度优先搜索
	int visited[maxsize];//由于C语言没有布尔类型,用0表示未被访问,1表示该节点已被访问
	for (int i = 0; i < l->dots; i++)    visited[i] = 0;
	for (int i = 0; i < l->dots; i++) {
		if (!visited[i])	DFS(l, i,visited);
	}
}

2.邻接表的广度优先 搜索,利用队列进行

void BFStraverse(list l) {
	int visited[maxsize];//由于C语言没有布尔类型,用0表示未被访问,1表示该节点已被访问
	for (int i = 0; i < l->dots; i++)    visited[i] = 0;//把所有节点设为未访问
	quene s = createquene();
	for (int i = 0; i < l->dots; i++) {
		if (!visited[i]) {//遍历所有节点,若已被遍历则i+1
			visited[i] = 1;	//若没遍历则把该节点设为以遍历
			printf("正在遍历第%d个节点",i);
			insertquene(s, i);//将i插入队列
			while (!isempty(s)) {
				int u = deletex(s);//弹出最先入队列的元素u
				linenode w = l->G[u].firstedge;//找到u对应的链表头节点
				while (w) {
					if (!visited[w->dot]){//把u对应的所有节点都遍历并插入队列
						visited[w->dot] = 1;//表示该节点以遍历
						printf("正在遍历第%d个节点", w->dot);
						insertquene(s, w->dot);
						w = w->next;
					}
				}
			}
		}
	}
}

邻接矩阵的深度优先搜索

//邻接矩阵的深度优先搜索
void DFS(graph l, int* visited, int x) {
	visited[x] = 1;
	printf("正在访问%d节点",x);
	for (int j = 0; j < l->dot; j++) {
		if (!visited[j] && l->map[x][j] == 1)//当节点未被访问并且i,j有边
			DFS(l, visited, j);
	}
}
void DFStraverse(graph l) {
	int visited[maxsize];//由于C语言没有布尔类型,用0表示未被访问,1表示该节点已被访问
	for (int i = 0; i < l->dot; i++)    visited[i] = 0;
	for(int i = 0; i < l->dot;i++) {
		if (!visited[i]) {
			DFS(l, visited, i);
		}
	}
}

邻接矩阵的广度优先搜索

void BFStraverse(graph l) {
	int visited[Maxsize];
	quene q = createquene();
	for (int i = 0; i < l->dot; i++)    visited[i] = 0;
	for (int i = 0; i < l->dot; i++) {
		if (!visited[i]) {
			visited[i] = 1;
			insertquene(q, i);
			printf("正在访问%d个节点", i);
			while (!isempty(q)) {
				int z = deletex(q);
				for (int j = 0; j < l->dot; j++) {
					if (!visited[j] && l->map[z][j] == 1) {
						insertquene(q, j);
						visited[j] = 1;
						printf("正在访问%d个节点", j);
					}
				}
			}
		}
	}
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值