#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;
}
图(构图 ,图的应用, BSF遍历, DSF遍历) 相关代码 的学习记录
最新推荐文章于 2022-09-27 14:11:22 发布