邻接表图,增加、删除、修改,功能齐全,有双权和有单权

刚刚考完,纪念一下,虽说不是考试提交的最终代码,但是是我提前准备的考试源码,供给考试使用。

这是单权

下面是双权的



#include <stdio.h>
#include <stdlib.h>
#include <conio.h>
#include <string.h>
#include <malloc.h>


/*
*			有向带权图
 */


 //	弧的结点结构体定义
typedef struct arcnode
{
	int adjvex;	//	该弧的终点位置,整型数据,存顶点在表中的位置
	struct arcnode *nextarc;	//	指向下一条弧的指针
	int distance;		//	弧的相关信息,用来存放权值
	int time;
} arcnode;

//	顶点的结点结构体定义
typedef struct vexnode
{
	char data;	//	顶点信息
	struct arcnode *firstarc;	//	指向第一条弧的指针
} vexnode;

//typedef vexnode adjlist[20];

typedef struct
{
	vexnode adjlist[20];	//	邻接表
	int vexnum;		//	顶点数
	int arcnum;		//	边数
} ALGraph;

typedef struct queue
{
	int queue[20];
	int front;
	int rear;
} queue;

后加的
#define MAX 20
#define INF         (~(0x1<<31))        // 最大值(即0X7FFFFFFF)
#define isLetter(a) ((((a)>='a')&&((a)<='z')) || (((a)>='A')&&((a)<='Z')))
#define LENGTH(a)   (sizeof(a)/sizeof(a[0]))
typedef enum MyEnum_
{
	DISTANCE,
	TIME
}MyEnum;
// 边的结构体
typedef struct _edata
{
	char start; // 边的起点
	char end;   // 边的终点
	int distance; // 边的权重
	int time;   // 边的时间
}EData;

// 顶点
static char  gVexs[] = { 'A', 'B', 'C', 'D', 'E', 'F', 'G' };
// 边//无向图用
static EData gEdges[] = {
	// 起点 终点 权
	  {'A', 'B', 12, 2},
	  {'A', 'F', 16, 8},
	  {'A', 'G', 14, 7},
	  {'B', 'C', 10, 5},
	  {'B', 'F',  7, 13},
	  {'C', 'D',  3, 9},
	  {'C', 'E',  5, 12},
	  {'C', 'F',  6, 11},
	  {'D', 'E',  4, 3},
	  {'E', 'F',  2, 6},
	  {'E', 'G',  8, 10},
	  {'F', 'G',  9, 4},
};
// 边//有向图用
static EData gEdges_one[] = {
	// 起点 终点 权
	  {'A', 'B', 12, 2},
	  {'B', 'C', 10, 5},
	  {'C', 'E', 5, 12},
	  {'C', 'F', 6, 11},
	  {'D', 'C', 3, 9},
	  {'D', 'E', 4, 3},
	  {'E', 'G', 8, 10},
	  {'F', 'A', 16, 8},
	  {'F', 'B', 7, 13},
	  {'F', 'E', 2, 6},
	  {'G', 'A', 14, 7},
	  {'G', 'F', 9, 4},
};
//

void InitGraph(ALGraph *ALG);
void AddVex(ALGraph *ALG, char vex);
void DisplayVexs(ALGraph *ALG);
void AddArc(ALGraph *ALG, int index1, int index2, int distance, int time);
int GetIndexOfVexs(ALGraph *ALG, char vex);
void DisplayArcs(ALGraph *ALG);
void DeleteVex(ALGraph *ALG, int index);
void DeleteArc(ALGraph *ALG, int index1, int index2);
void DFSTraversal(ALGraph *ALG, int index);
void BFSTraversal(ALGraph *ALG, int index);
void InitVisit(ALGraph *ALG);
void InitQueue(queue *q);
void enqueue(queue *q, int data);
int dequeue(queue *q);


后加的
void create_example_lgraph(ALGraph *ALG);
void link_last(arcnode *list, arcnode *node);
void DFS(ALGraph *ALG);
void BFS(ALGraph *ALG);
void dijkstra(const ALGraph *G, int vs, int prev[], int dist[], MyEnum a);
int get_distance_time(const ALGraph *G, int start, int end, MyEnum a);
void displaypath(const ALGraph *G, int prev[], int start, int end);
void create_example_lgraph_one(ALGraph * ALG);
void initarray(ALGraph *ALG, int prev[], int dist[]);

/

int visit[20];
queue Q;

int main()
{

	printf("========================================    MENU    =================================================================\n");
	printf("=|exit:0 | Init:1 | AddVex:2 | AddArc:3 | DispVexs:4 | DispArcs:5 | DelArc:6 | DelVex:7 | DFS:8 | BFS:9 | dijkstra:10|=\n");
	printf("=====================================================================================================================\n");


	int choice;
	int index1, index2, distance, time;

	char ch;
	int j;
	ALGraph G;

	int prev[MAX] = { 0 };  //存储前驱结点
	int dist[MAX] = { 0 };  //存储某点到各点最短路程	
//	printf("%d\n", sizeof(ALGraph));
	InitGraph(&G);
//	create_example_lgraph_one(&G);  //有向图例图
	create_example_lgraph(&G);  //无向图例题

	printf("\nchoice : ");
	scanf_s("\t%d", &choice);
	while (choice) {
		switch (choice) {
		case 0: exit(1);
			break;
		case 1: InitGraph(&G);
			printf(">>>初始化完成 !\n");
			break;
		case 2: //	AddVex:2
			printf(">>>输入增加的顶点: ");
			scanf_s("\t%c", &ch, sizeof(ch));
			AddVex(&G, ch);
			printf(">>>增加顶点成功 !\n");
			break;
		case 3: //	AddArc:3
			printf(">>>请输入弧尾 : ");
			scanf_s("\t%c", &ch, sizeof(ch));
			index1 = GetIndexOfVexs(&G, ch);
			if (index1 != -1)
			{
				printf(">>>请输入弧头 : ");
				scanf_s("\t%c", &ch, sizeof(ch));
				index2 = GetIndexOfVexs(&G, ch);
				if (index2 != -1)
				{
					printf(">>>请输入权值 : ");
					scanf_s("\t%d", &distance);
					printf(">>>请输入时间 : ");
					scanf_s("\t%d", &time);
					AddArc(&G, index1, index2, distance, time);
					AddArc(&G, index2, index1, distance, time);
					printf(">>>增加弧成功 !\n");
				}
				else
					printf(">>>图中没有此顶点\n");
			}
			else
				printf(">>>图中没有此顶点\n");
			break;
		case 4: //	DispVexs:4
			DisplayVexs(&G);
			break;
		case 5: //	DispAdjMatrix:5
			DisplayArcs(&G);
			break;
		case 6: //	DeleteArc
			printf(">>>请输入弧尾 : ");
			scanf_s("\t%c", &ch, sizeof(ch));
			index1 = GetIndexOfVexs(&G, ch);
			if (index1 != -1)
			{
				printf(">>>请输入弧头 : ");
				scanf_s("\t%c", &ch, sizeof(ch));
				index2 = GetIndexOfVexs(&G, ch);
				if (index2 != -1)
				{
					DeleteArc(&G, index1, index2);//删除一条弧 
					DeleteArc(&G, index2, index1);//删除一条弧
					printf(">>>删除弧成功 !\n");
				}
				else
					printf(">>>图中没有此顶点\n");
			}
			else
				printf(">>>图中没有此顶点\n");
			break;
		case 7: //	DeleteVex
			printf(">>>输入删除的顶点: ");
			scanf_s("\t%c", &ch, sizeof(ch));
			index1 = GetIndexOfVexs(&G, ch);
			if (index1 != -1)
			{
				DeleteVex(&G, index1);
				printf(">>>删除顶点成功 !\n");
			}
			else
				printf(">>>图中没有此顶点\n");
			break;
		case 8: //	DFS
			InitVisit(&G);
			printf(">>>输入起点 : ");
			scanf_s("\t%c", &ch, sizeof(ch));
			index1 = GetIndexOfVexs(&G, ch);
			if (index1 == -1)
			{
				printf("没有这个点\n");
				break;
			}

			printf("深度优先搜索结果:\t");
			do {
				DFSTraversal(&G, index1);
				for (j = 0; j < G.vexnum; ++j)  //可能同时又多个未连接的图,需要寻找
				{
					if (visit[j] == 0)
					{
						index1 = j;
						break;
					}
				}
			} while (j < G.vexnum);
			printf("\n");
			break;
		case 9: //	BFS
			InitVisit(&G);
			InitQueue(&Q);
			printf(">>>输入起点 : ");
			scanf_s("\t%c", &ch, sizeof(ch));
			index1 = GetIndexOfVexs(&G, ch);
			if (index1 == -1)
			{
				printf("没有这个点\n");
				break;
			}

			printf("广度优先搜索结果:\t");
			do {
				BFSTraversal(&G, index1);
				for (j = 0; j < G.vexnum; ++j)
				{
					if (visit[j] == 0)
					{
						index1 = j;
						break;
					}
				}
			} while (j < G.vexnum);
			printf("\n");
			break;
		case 10:
			initarray(&G, prev, dist);
			printf(">>>输入起点 : ");
			scanf_s("\t%c", &ch, sizeof(ch));
			index1 = GetIndexOfVexs(&G, ch);
			if (index1 != -1)
			{
				printf(">>>输入终点 : ");
				scanf_s("\t%c", &ch, sizeof(ch));
				index2 = GetIndexOfVexs(&G, ch);
				if (index2 != -1)
				{
					printf(">>>1 寻找路径最短 2 寻找时间最短:");
					scanf_s("\t%c", &ch, sizeof(ch));
					if (ch == '1')
					{
						dijkstra(&G, index1, prev, dist, DISTANCE);  // 测试权值
						displaypath(&G, prev, index1, index2);
					}
					else if (ch == '2')
					{
						dijkstra(&G, index1, prev, dist, TIME);  //测试时间
						displaypath(&G, prev, index1, index2);
					}
					else
						printf("输入错误\n");
				}
				else
					printf(">>>图中没有此顶点\n");
			}
			else
				printf(">>>图中没有此顶点\n");
			break;

		default: 
			printf("错误的输入选择!!!\n");
			getchar();
		}
		printf("\nchoice : ");
		scanf_s("\t%d", &choice);
	}

	return 0;
}

//初始化
void InitGraph(ALGraph *ALG)
{
	ALG->vexnum = 0;
	ALG->arcnum = 0;
}

void initarray(ALGraph *ALG, int prev[], int dist[])
{
	int i;
	for (i = 0; i < ALG->vexnum; ++i)
	{
		prev[i] = 0;
		dist[i] = 0;
	}
}

//在顶点数组中搜索vex的位置下标,从0开始
int GetIndexOfVexs(ALGraph *ALG, char vex)
{
	int i;
	for (i = 0; i < ALG->vexnum; ++i)
	{
		if (ALG->adjlist[i].data == vex) return i;
	}
	return -1;
}

//增加顶点
void AddVex(ALGraph *ALG, char vex)
{
	ALG->adjlist[ALG->vexnum].data = vex;
	ALG->adjlist[ALG->vexnum].firstarc = NULL;
	ALG->vexnum++;
}

//显示顶点
void DisplayVexs(ALGraph *ALG)
{
	int i;
	printf("\n\t[  ");
	for (i = 0; i < ALG->vexnum; ++i)
	{
		printf("%c  ", ALG->adjlist[i].data);
	}
	printf("]\n");
}

//增加一条弧
//index1弧头(起点),index2弧尾(终点)
void AddArc(ALGraph *ALG, int index1, int index2, int distance, int time)
{
	arcnode *p, *q;
	q = (arcnode*)malloc(sizeof(arcnode));
	q->adjvex = index2;
	q->nextarc = NULL;
	q->distance = distance;
	q->time = time;
	//	下面的代码,有向图执行一次,无向图要将 index1 换成 index2,再执行一遍;
	p = ALG->adjlist[index1].firstarc;
	if (p == NULL)          //第一种情况,顶点指向没有时,直接加上
	{
		ALG->adjlist[index1].firstarc = q;
		ALG->arcnum++;
	}
	else
	{
		while (p)
		{
			if (p->adjvex == index2)
			{
				p->distance = distance;
				p->time = time;
				printf(">>>该弧已经存在,无法再增加,进行修改权值\n");
				return;
			}
			else if (p->nextarc) p = p->nextarc;    //第二种情况,循环寻找是不是弧链表最后一个
			else break;                              //找到跳出
		}
		p->nextarc = q;
		ALG->arcnum++;
	}
	//printf(">>>弧的数量为: %d\n", ALG->arcnum);

}

//显示弧
void DisplayArcs(ALGraph *ALG)
{
	int i, distance, time;
	char vex1, vex2;
	arcnode *p;
	
	for (i = 0; i < ALG->vexnum; ++i)   //遍历每个顶点
	{
		printf(">>>");
		p = ALG->adjlist[i].firstarc;
		vex1 = ALG->adjlist[i].data;
		while (p)
		{
			vex2 = ALG->adjlist[p->adjvex].data;  //找到指向弧头位置的数据
			distance = p->distance;
			time = p->time;
			printf("(%c,%c)<D:%d><T:%d>   ", vex1, vex2, distance, time);
			p = p->nextarc;
		}
		printf("\n");  //调整格式
	}
	printf("\n>>>弧的数量为: %d\n", ALG->arcnum);
}

//删除顶点的辅助函数:递归调用删除弧结点内容 
int DeleteAssist(arcnode *p)
{
	if (p)
	{
		DeleteAssist(p->nextarc);
		free(p);
		return 1;
	}
	else
		return 0;
}

//删除数组中节点  //删除index位置所有有关的弧和点信息
void DeleteVex(ALGraph *ALG, int index)
{
	arcnode *p, *del, *pre = NULL;
	int i;

	p = ALG->adjlist[index].firstarc;
	while (p)  //感觉暂时没有用处
	{
		ALG->arcnum--;
		p = p->nextarc;
	}
	DeleteAssist(ALG->adjlist[index].firstarc);  //删除这个顶点储存的弧信息

	for (i = index; i < ALG->vexnum - 1; i++)  //数组内容移位 
	{
		ALG->adjlist[i].data = ALG->adjlist[i + 1].data;
		ALG->adjlist[i].firstarc = ALG->adjlist[i + 1].firstarc;  //顶点信息和第一条弧的指针都移位 
	}
	ALG->adjlist[ALG->vexnum - 1].data = -1;   //最后一个数组结点初始化掉
	ALG->adjlist[ALG->vexnum - 1].firstarc = NULL;
	ALG->vexnum--;    //顶点个数减1                       

	for (i = 0; i < ALG->vexnum; i++)  //删除所有头是index的弧
	{
		p = ALG->adjlist[i].firstarc;
		while (p)
		{
			if (p->adjvex == index)
			{
				if (p == ALG->adjlist[i].firstarc)
				{
					del = p;
					p = p->nextarc;
					ALG->adjlist[i].firstarc = p;
					pre = NULL;
					free(del);
				}
				else
				{
					del = p;
					p = p->nextarc;
					pre->nextarc = p;
					free(del);
				}
				ALG->arcnum--;  //前面没有删除点的弧时候没有减所以减双倍的
			}
			if (p != NULL)
			{
				if (p->adjvex > index)
				{
					p->adjvex--;
				}
			}
			else
				break;
			pre = p;
			p = p->nextarc;
		}

	}
}

//删除弧 只删除从index1到index2的弧
void DeleteArc(ALGraph *ALG, int index1, int index2)
{
	arcnode *p, *q;
	p = ALG->adjlist[index1].firstarc;
	if (p->adjvex == index2)//p为头结点的情况 
	{
		q = p;
		ALG->adjlist[index1].firstarc = p->nextarc;
		free(q);
		ALG->arcnum--;//边个数减一 
		return;
	}
	//p = ALG->adjlist[index1].firstarc;
	while (p->nextarc != NULL)
	{
		if (p->nextarc->adjvex == index2)
		{
			q = p->nextarc;
			p->nextarc = q->nextarc;
			free(q);
			break;
		}
		p = p->nextarc;
	}
	ALG->arcnum--;//边个数减一 
}


//图的深度搜索
void DFSTraversal(ALGraph *ALG, int index)
{
	arcnode *p;

	if (index < 0 || index >= ALG->vexnum)
		return;

	visit[index] = 1;  //先标记
	printf(" --> %c", ALG->adjlist[index].data);
	p = ALG->adjlist[index].firstarc;  //拿到下一个顶点链表地址
	while (p)
	{
		if (visit[p->adjvex] == 0) DFSTraversal(ALG, p->adjvex);  //如果这个顶点没有访问,就进行深度搜索
		p = p->nextarc;  
	}
}

//图的广度搜索
void BFSTraversal(ALGraph *ALG, int index)
{
	
	arcnode *p;
	int j;

	if (index < 0 || index >= ALG->vexnum)
		return ;

	visit[index] = 1;  //先标记
	printf(" --> %c", ALG->adjlist[index].data);
	p = ALG->adjlist[index].firstarc;
	while (p)   //每次寻找一层
	{
		if (visit[p->adjvex] == 0)  //没有访问过就入队
		{
			//printf("\n\np->adjvex=%d\n\n", p->adjvex);
			enqueue(&Q, p->adjvex);
			visit[p->adjvex] = 1;
		}
		p = p->nextarc;
	}

	j = dequeue(&Q);  //出队
	//printf("\n\nj=%d\n\n", j);
	if (j != -1)
	{
		BFSTraversal(ALG, j);  //从新的顶点开始广度搜索
	}
}

图的广度搜索//不用递归
//void BFSTraversal(ALGraph *ALG, int index)
//{
//	int j, k;  //
//	arcnode *node = NULL;
//
//  if (index < 0 || index >= ALG->vexnum)
//		return ;
//	if (!visit[index])
//	{
//		visit[index] = 1;
//		printf("--> %c", ALG->adjlist[index].data);
//		enqueue(&Q, index);
//	}
//
//	while (Q.front != Q.rear)
//	{
//		j = dequeue(&Q);  //出队
//		node = ALG->adjlist[j].firstarc;
//		while (node != NULL)
//		{
//			k = node->adjvex;
//			if (!visit[k])
//			{
//				visit[k] = 1;
//				printf("--> %c", ALG->adjlist[k].data);
//				enqueue(&Q, k);  //入队
//			}
//			node = node->nextarc;
//		}
//	}
//	printf("\n");
//}

//初始化访问数组
void InitVisit(ALGraph *ALG)
{
	int i;
	for (i = 0; i < ALG->vexnum; ++i)
	{
		visit[i] = 0;
	}
}

//初始化队列
void InitQueue(queue *q)
{
	q->front = 0;
	q->rear = 0;
}

//入队
void enqueue(queue *q, int data)
{
	q->queue[q->rear++] = data;
}

//出队
int dequeue(queue *q)
{
	if (q->front != q->rear)
	{
		return q->queue[q->front++];
	}
	return -1;
}

//将node链接到list的末尾
void link_last(arcnode *list, arcnode *node)
{
	arcnode *p = list;

	while (p->nextarc)
	{
		p = p->nextarc;
	}
	p->nextarc = node;
}


//创造一个例图//是无向图的
void create_example_lgraph(ALGraph * ALG)
{
	char c1, c2;
	int vlen = LENGTH(gVexs);  //点
	int alen = LENGTH(gEdges);  //边
	int i, p1, p2;
	int distance, time;
	arcnode *node1, *node2;

	InitGraph(ALG);  //初始化

	//初始化 顶点数 边数
	ALG->vexnum = vlen;
	ALG->arcnum = alen * 2;  //边数是二倍的

	//初始化 领接表 的顶点
	for (i = 0; i < ALG->vexnum; i++)
	{
		ALG->adjlist[i].data = gVexs[i];
		ALG->adjlist[i].firstarc = NULL;
	}

	//初始化 领接表 的边
	for (i = 0; i < alen; i++)
	{
		// 读取边的起始顶点,结束顶点,权
		c1 = gEdges[i].start;
		c2 = gEdges[i].end;
		distance = gEdges[i].distance;
		time = gEdges[i].time;

		p1 = GetIndexOfVexs(ALG, c1);
		p2 = GetIndexOfVexs(ALG, c2);

		// 初始化node1
		node1 = (arcnode*)malloc(sizeof(arcnode));
		node1->adjvex = p2;
		node1->distance = distance;
		node1->time = time;
		node1->nextarc = NULL;
		// 将node1链接到"p1所在链表的末尾"
		if (ALG->adjlist[p1].firstarc == NULL)
			ALG->adjlist[p1].firstarc = node1;
		else
			link_last(ALG->adjlist[p1].firstarc, node1);
		// 初始化node2
		node2 = (arcnode*)malloc(sizeof(arcnode));
		node2->adjvex = p1;
		node2->distance = distance;
		node2->time = time;
		node2->nextarc = NULL;
		// 将node2链接到"p2所在链表的末尾"
		if (ALG->adjlist[p2].firstarc == NULL)
			ALG->adjlist[p2].firstarc = node2;
		else
			link_last(ALG->adjlist[p2].firstarc, node2);
	}

}

//创造一个例图//是有向图的
void create_example_lgraph_one(ALGraph * ALG)
{
	char c1, c2;
	int vlen = LENGTH(gVexs);  //点
	int alen = LENGTH(gEdges_one);  //边
	int i, p1, p2;
	int distance, time;
	arcnode *node1;

	InitGraph(ALG);  //初始化

	//初始化 顶点数 边数
	ALG->vexnum = vlen;
	ALG->arcnum = alen;  //边数

	//初始化 领接表 的顶点
	for (i = 0; i < ALG->vexnum; i++)
	{
		ALG->adjlist[i].data = gVexs[i];
		ALG->adjlist[i].firstarc = NULL;
	}

	//初始化 领接表 的边
	for (i = 0; i < alen; i++)
	{
		// 读取边的起始顶点,结束顶点,权
		c1 = gEdges_one[i].start;
		c2 = gEdges_one[i].end;
		distance = gEdges_one[i].distance;
		time = gEdges_one[i].time;

		p1 = GetIndexOfVexs(ALG, c1);
		p2 = GetIndexOfVexs(ALG, c2);

		// 初始化node1
		node1 = (arcnode*)malloc(sizeof(arcnode));
		node1->adjvex = p2;
		node1->distance = distance;
		node1->time = time;
		node1->nextarc = NULL;
		// 将node1链接到"p1所在链表的末尾"
		if (ALG->adjlist[p1].firstarc == NULL)
			ALG->adjlist[p1].firstarc = node1;
		else
			link_last(ALG->adjlist[p1].firstarc, node1);
		 初始化node2
		//node2 = (arcnode*)malloc(sizeof(arcnode));
		//node2->adjvex = p1;
		//node2->distance = distance;
		//node2->nextarc = NULL;
		 将node2链接到"p2所在链表的末尾"
		//if (ALG->adjlist[p2].firstarc == NULL)
		//	ALG->adjlist[p2].firstarc = node2;
		//else
		//	link_last(ALG->adjlist[p2].firstarc, node2);
	}
}

//深度优先搜索
void DFS(ALGraph *ALG)
{
	char ch;
	int index1, j;

	InitVisit(ALG);
	printf(">>>输入起点 : ");
	scanf_s("\t%c", &ch, sizeof(ch));
	index1 = GetIndexOfVexs(ALG, ch);
	if (index1 == -1)
	{
		printf("没有这个点\n");
		return;
	}

	printf("深度优先搜索结果:\t");
	do {
		DFSTraversal(ALG, index1);
		for (j = 0; j < ALG->vexnum; ++j)  //可能同时又多个未连接的图,需要寻找
		{
			if (visit[j] == 0)
			{
				index1 = j;
				break;
			}
		}
	} while (j < ALG->vexnum);
	printf("\n");
}

//广度优先搜索
void BFS(ALGraph * ALG)
{
	char ch;
	int index1, j;

	InitQueue(&Q);  //初始化队列
	InitVisit(ALG);  //初始化访问标记数组
	 
	printf(">>>输入起点 : ");
	scanf_s("\t%c", &ch, sizeof(ch));
	index1 = GetIndexOfVexs(ALG, ch);
	if (index1 == -1)
	{
		printf("没有这个点\n");
		return;
	}

	do {
		printf("广度优先搜索结果:\t");
		BFSTraversal(ALG, index1);
		for (j = 0; j < ALG->vexnum; ++j)
		{
			if (visit[j] == 0)
			{
				index1 = j;
				break;
			}
		}
	} while (j < ALG->vexnum);
	printf("\n");
}

/*
 * 获取G中边<start, end>的权值或者时间;若start和end不是连通的,则返回无穷大。
 */
int get_distance_time(const ALGraph *G, int start, int end, MyEnum a)
{
	arcnode *node;

	if (start == end)
		return 0;

	node = G->adjlist[start].firstarc;
	if (a == DISTANCE)
	{
		while (node != NULL)
		{
			if (end == node->adjvex)
				return node->distance;
			node = node->nextarc;
		}
	}
	else if (a == TIME)
	{
		while (node != NULL)
		{
			if (end == node->adjvex)
				return node->time;
			node = node->nextarc;
		}
	}

	return INF;
}

/*
 * Dijkstra最短路径。
 * 即,统计图(G)中"顶点vs"到其它各个顶点的最短路径。
 *
 * 参数说明:
 *        G -- 图
 *       vs -- 起始顶点(start vertex)。即计算"顶点vs"到其它顶点的最短路径。
 *     prev -- 前驱顶点数组。即,prev[i]的值是"顶点vs"到"顶点i"的最短路径所经历的全部顶点中,位于"顶点i"之前的那个顶点。
 *     dist -- 长度数组。即,dist[i]是"顶点vs"到"顶点i"的最短路径的长度。
 */
void dijkstra(const ALGraph *G, int vs, int prev[], int dist[], MyEnum a)
{
	int i, j, k;
	int min;
	int tmp;
	int flag[MAX];      // flag[i]=1表示"顶点vs"到"顶点i"的最短路径已成功获取。

	if (vs < 0 || vs >= G->vexnum)  //
	{
		return;
	}

	// 初始化
	if (a == DISTANCE)
	{
		for (i = 0; i < G->vexnum; i++)
		{
			flag[i] = 0;                    // 顶点i的最短路径还没获取到。
			prev[i] = vs;                    // 顶点i的前驱顶点为0。
			dist[i] = get_distance_time(G, vs, i, DISTANCE);  // 顶点i的最短路径为"顶点vs"到"顶点i"的权。
		}
	}
	else if (a == TIME)
	{
		for (i = 0; i < G->vexnum; i++)
		{
			flag[i] = 0;                    // 顶点i的最短路径还没获取到。
			prev[i] = vs;                    // 顶点i的前驱顶点为0。
			dist[i] = get_distance_time(G, vs, i, TIME);  // 顶点i的最短路径为"顶点vs"到"顶点i"的时间。
		}
	}

	// 对"顶点vs"自身进行初始化
	flag[vs] = 1;
	dist[vs] = 0;

	// 遍历G->vexnum-1次;每次找出一个顶点的最短路径。
	for (i = 1; i < G->vexnum; i++)
	{
		// 寻找当前最小的路径;
		// 即,在未获取最短路径的顶点中,找到离vs最近的顶点(k)。
		min = INF;
		for (j = 0; j < G->vexnum; j++)
		{
			if (flag[j] == 0 && dist[j] < min)
			{
				min = dist[j];
				k = j;
			}
		}
		// 标记"顶点k"为已经获取到最短路径
		flag[k] = 1;

		// 修正当前最短路径和前驱顶点
		// 即,当已经"顶点k的最短路径"之后,更新"未获取最短路径的顶点的最短路径和前驱顶点"。
		if (a == DISTANCE)
		{
			for (j = 0; j < G->vexnum; j++)
			{
				tmp = get_distance_time(G, k, j, DISTANCE);
				tmp = (tmp == INF ? INF : (min + tmp)); // 防止溢出
				if (flag[j] == 0 && (tmp < dist[j]))
				{
					dist[j] = tmp;
					prev[j] = k;
				}
			}
		}
		else if (a == TIME)
		{
			for (j = 0; j < G->vexnum; j++)
			{
				tmp = get_distance_time(G, k, j, TIME);
				tmp = (tmp == INF ? INF : (min + tmp)); // 防止溢出
				if (flag[j] == 0 && (tmp < dist[j]))
				{
					dist[j] = tmp;
					prev[j] = k;
				}
			}
		}
	}

	// 打印dijkstra最短路径的结果
	if (a == DISTANCE)
		printf("最短路径(%c): \n", G->adjlist[vs].data);
	else if (a == TIME)
		printf("最短时间(%c): \n", G->adjlist[vs].data);

	for (i = 0; i < G->vexnum; i++)
		printf("  最短(%c, %c)=%d\n", G->adjlist[vs].data, G->adjlist[i].data, dist[i]);	
	printf("\n");
}

//打印某点到另一点路径
void displaypath(const ALGraph *G, int prev[], int start, int end)
{
	//用来输出所有路径   //可以考虑用栈
	char* str = NULL;
	int pos;  //用来标记位置
	int m = 0;  //m用来计数

	if ((str = (char*)malloc(sizeof(char)*G->vexnum)) == NULL)   //用来存储输出字符
		return;

	pos = prev[end];  //pos最先指向end的前驱结点位置
	for (m = 0; m < G->vexnum; m++)  //循环寻找前驱结点
	{
		str[m] = G->adjlist[pos].data;
		if (str[m] == G->adjlist[start].data)  //如果是出发点,就不用再找了
		{
			break;
		}
		pos = prev[pos];  //寻找下一个位置
	}
	for (int j = m; j >= 0; j--)
	{
		printf("%c-> ", str[j]);
	}
	printf("%c\n", G->adjlist[end].data);
	free(str);
}



这是单权

  • 2
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值