图(构图 ,图的应用, BSF遍历, DSF遍历) 相关代码 的学习记录

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

#define TypeE int
#define TypeV int
#define MaxVertexNum 20
#define MAXSIZE 69999

typedef struct {
	TypeE G[MaxVertexNum][MaxVertexNum]; //邻接矩阵
	TypeV vex[MaxVertexNum]; //顶点数组,存储目标数据 
	TypeE numEdges; //边数 
	TypeV numVertexes; //顶点数  	
}MGraph;

typedef struct QNode {
	int data;
	struct QNode* next;
}QNode , *QueuePtr;

typedef struct
{
	QueuePtr front, rear;//队头, 队尾
}LinkQueue;

void ShowGraph(MGraph* p)//显示图
{
	int i, j;

	printf("\n顶点数据:\t");
	for (i = 0; i < p->numVertexes; i++) {//输入结点数据
		printf("%d  ", p->vex[i]);
	}

	printf("\n邻接矩阵: \n");
	for (i = 0; i < p->numVertexes; i++) {
		for (j = 0; j < p->numVertexes; j++) {
			printf("%d  ", p->G[i][j]);//邻接矩阵
		}
		printf("\n");
	}

}

MGraph* CreateNode()//创造结点 
{
	MGraph* p = (MGraph*)malloc(sizeof(MGraph));

	if (p)//如果申请成功 
		return p;
	else
		return NULL;
}

void CreateGraph(MGraph* p)//构图
{
	int i, j, k, w;
	printf("顶点数:\t");
	scanf_s("%d", &p->numVertexes);
	printf("边数:\t");
	scanf_s("%d", &p->numEdges);

	printf("输入顶点数据:\n");
	for (i = 0; i < p->numVertexes; i++)
		scanf_s("%d", &p->vex[i]);//顶点数据 

	for (i = 0; i < p->numVertexes; i++) {
		for (j = 0; j < p->numVertexes; j++) {
			p->G[i][j] = MAXSIZE;//初始化邻接矩阵 
			if (i == j) p->G[i][j] = 0;
		}
	}



	for (k = 0; k < p->numEdges; k++) {
		printf("输入G<i,j>中下标i,j以及权w :\n");
		scanf_s("%d %d %d", &i, &j, &w);
		p->G[i][j] = w;//赋权 
		p->G[j][i] = p->G[i][j];//无向图对称 
	}

}
//D[]用来存储每个点的最短路径,即最低权值,P[]用来存储路径,即顶点号 
//图的应用---最短路径---Dijkstra算法
void ShortestPath_Dijkstra(MGraph* p, int* P, int* D, int V0)
{//Dijkstra算法目的是: 求出单个结点V0到其他每个结点的最短路径
	int i, j, k = 0;
	int finish[MaxVertexNum];//finish[]==1表示取得最小路径 
	int min = MAXSIZE;//最小路径 

	for (i = 0; i < p->numVertexes; i++)
	{
		finish[i] = 0;//全部未取得最小路径 
		D[i] = p->G[V0][i];//记录起始点于其余顶点的路径值 
		P[i] = 0;//没有路径 
	}
	finish[V0] = 1;//表示起点本身已经取得最小路径 
	D[V0] = 0;//到本身路径值为0 

	for (i = 1; i < p->numVertexes; i++)
	{
		min = MAXSIZE;
		for (j = 0; j < p->numVertexes; j++)
		{//未求出最小路径且相邻路径值最小 
			if (!finish[j] && D[j] < min) {
				min = D[j];//记录 
				k = j;//记录 
			}
		}//最终选择出最小路径 
		finish[k] = 1; //表示取得该点最小路径 
		//路径修正 
		for (j = 0; j < p->numVertexes; j++)
		{//当前路径小于之前路径 
			if (!finish[j] && min + p->G[k][j] < D[j]) {
				D[j] = min + p->G[k][j];
				P[j] = k;
			}
		}
	}
	printf("\n单源最短路径:\n");
	//计算完后的显示
	for (i = 0; i < p->numVertexes; i++) {
		printf("V%d到V%d的最短路径为 %d\n", V0, i, D[i]);
		printf("V%d<-V%d : ", p->numVertexes - 1 - i, V0);
		for (j = p->numVertexes - 1 - i; P[j] != j; j = P[j]) {
			printf("V%d<-", j);
		}
		printf("V%d\n", j);
	}

}

int P1[MaxVertexNum][MaxVertexNum];
int D1[MaxVertexNum][MaxVertexNum];

//图的应用---最短路径---Floyd算法
void ShortestPath_Floyd(MGraph* p)
{
	int i, j, k;
	for (i = 0; i < p->numVertexes; i++) {
		for (j = 0; j < p->numVertexes; j++) {
			D1[i][j] = p->G[i][j];//D1[i][j]值即为对应点间的权值
			P1[i][j] = j;//初始化P1
		}
	}

	for (k = 0; k < p->numVertexes; k++) {//中继结点
		for (i = 0; i < p->numVertexes; i++) {//前继结点
			for (j = 0; j < p->numVertexes; j++) {//后继结点
				if (D1[i][k] + D1[k][j] < D1[i][j]) {
					D1[i][j] = D1[i][k] + D1[k][j];//选择更小的权值
					P1[i][j] = P1[i][k];/*路径设置经过下标为K的顶点*/
				}
			}
		}
	}
	printf("\n多源最短路径:\n");
	//显示
	for (i = 0; i < p->numVertexes; i++) {
		for (j = i + 1; j < p->numVertexes; j++) {
			k = P1[i][j];
			while (k != j) {
				printf("->V%d", k);
				k = P1[k][j];
			}
			printf("->V%d", k);
		}
		printf("\n");
	}


}

int visited[MaxVertexNum];//1表示访问过,0表示未访问过
void DFS(MGraph* p, int i)
{
	int j;
	visited[i] = 1;//设置为访问过

	printf("%d ", p->vex[i] );
	for (j = 0; j < p->numVertexes; j++) {
		if (!visited[j] && p->G[i][j] < MaxVertexNum && p->G[i][j] > 0)
			DFS( p, j);
	}

}
/*邻接矩阵的深度遍历操作*/
void DFSTraverse(MGraph* p)
{
	int i;
	for (i = 0; i < p->numVertexes; i++) 
		visited[i] = 0;//将全部结点设置为未访问
	
	for (i = 0; i < p->numVertexes; i++) {
		if (!visited[i])//若未被访问过
			DFS(p, i);
	}
}
/*将尾元素入队列*/
int EnQueue(LinkQueue* Q, int e)
{
	QueuePtr s = (QueuePtr)malloc(sizeof(QNode));
	if (!s)
		exit(1);
	s->data = e;
	s->next = NULL;
	Q->rear->next = s;

	Q->rear = s;
	return 1;
}
/*将首元素出队列*/
int DeQueue(LinkQueue* Q, int e)
{
	QueuePtr p;
	if (Q->front == Q->rear)
		return 0;
	p = Q->front->next;
	e = p->data;
	Q->front->next = p->next;

	if (Q->rear == p)
		Q->rear = Q->front;
	free(p);

	return e;
}
/*当前队列不为空*/
int QueueEmpty(LinkQueue* Q)
{
	if (Q->front == Q->rear)
		return 0;
	return 1;
}

void BSFTraverse(MGraph* p)
{
	int i, j;
	LinkQueue* Q = (LinkQueue* )malloc(sizeof(LinkQueue ));
	if (!Q) return;
	Q->front = NULL;
	Q->rear = NULL;
	QueuePtr head = (QueuePtr)malloc(sizeof(QNode));
	if (!head)
		return ;
	Q->rear = head;
	Q->front = head;

	for (i = 0; i < p->numVertexes; i++)
		visited[i] = 0;
	
	for (i = 0; i < p->numVertexes; i++) {
		if (!visited[i]) {            /*若是未访问过就处理*/
			visited[i] = 1;         
			printf("%d ", p->vex[i]);/*打印顶点,也可以其他操作*/
			EnQueue(Q, i);/*将此顶点入队列*/
			while (!QueueEmpty(Q)) {/*若当前队列不为空*/
				DeQueue(Q, i);
				for (j = 0; j < p->numVertexes; j++) {
					/*判断其他顶点若与当前顶点存在边且未访问过*/
					if (p->G[i][j] > 0 && p->G[i][j] < MAXSIZE && !visited[j]) {
						visited[j] = 1;/*将找到的此顶点标记为已访问*/
						printf("%d ", p->vex[j]);
						EnQueue(Q, j);/*将找到的此顶点入队列*/
					}
				}
			}
		}
	}

}

int main()
{
	int V0 = 0;
	int P[MaxVertexNum];
	int D[MaxVertexNum];


	MGraph* p = CreateNode();//建结点 

	CreateGraph(p);//构图 

	ShowGraph(p);//显示 

	ShortestPath_Dijkstra(p, P, D, V0);//计算VO到各个结点的结点

	ShortestPath_Floyd(p);
	
	printf("\n深度优先搜索\n");
	DFSTraverse(p);//DFS

	printf("\n广度优先搜索\n");
	BSFTraverse(p);//BFS
	printf("\n");
	return 0;
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值