Description
大家还记得邻接表类吗?没错,邻接表是表示稀疏图(边数比较少的图)的一种很好的数据结构。
下面要求实现创建邻接表、广度遍历、拓扑排序、最短路径等算法。
算法进根据已有代码段完成填空即可,不需要新定义变量,也不需要新写函数,注意输出提示及输出格式。
Input Format
第1行:图中结点的数量
第2行:图中有向边的数量
第3行:为n个顶点的值(int)
第4行开始:为顶点的对(弧),比如1 2 10,1和2为顶点的值,10为权值
最后1行:为迪杰斯特拉算法源点的值
Sample Input1
3
3
1 2 3
1 2 10
1 3 20
2 3 5
1
解释:
第1行:图中结点的数量为3
第2行:图中有向边的数量为3
第3行为n个顶点的值(int):1 2 3
第4行开始为顶点的对(弧尾 弧头 权值),分别是1 2 10,1 3 20,2 3 5,
最后一行为迪杰斯特拉算法源点的值 顶点1
Sample Output1
无向图G的邻接表形式:
1-->3(20)-->2(10)
2-->3(5)
3
图G的广度优先搜索序列为:1 3 2
图G的拓扑排序序列:1 2 3
拓扑排序成功
顶点1到顶点1的最短路径是:权值 = 0,顶点序列 =
顶点1到顶点2的最短路径是:权值 = 10,顶点序列 = 1 2
顶点1到顶点3的最短路径是:权值 = 15,顶点序列 = 1 2 3
Sample Input2
7
10
1 2 3 4 5 6 7
1 2 13
1 3 8
1 7 32
1 5 30
2 6 9
2 7 7
3 4 5
4 5 6
5 6 2
6 7 17
1
Sample Output2
无向图G的邻接表形式:
1-->5(30)-->7(32)-->3(8)-->2(13)
2-->7(7)-->6(9)
3-->4(5)
4-->5(6)
5-->6(2)
6-->7(17)
7
图G的广度优先搜索序列为:1 5 7 3 2 6 4
图G的拓扑排序序列:1 2 3 4 5 6 7
拓扑排序成功
顶点1到顶点1的最短路径是:权值 = 0,顶点序列 =
顶点1到顶点2的最短路径是:权值 = 13,顶点序列 = 1 2
顶点1到顶点3的最短路径是:权值 = 8,顶点序列 = 1 3
顶点1到顶点4的最短路径是:权值 = 13,顶点序列 = 1 3 4
顶点1到顶点5的最短路径是:权值 = 19,顶点序列 = 1 3 4 5
顶点1到顶点6的最短路径是:权值 = 21,顶点序列 = 1 3 4 5 6
顶点1到顶点7的最短路径是:权值 = 20,顶点序列 = 1 2 7
Sample Input3
4
5
1 2 3 4
1 2 30
1 3 5
3 2 10
2 4 40
4 3 50
1
Sample Output3
无向图G的邻接表形式:
1-->3(5)-->2(30)
2-->4(40)
3-->2(10)
4-->3(50)
图G的广度优先搜索序列为:1 3 2 4
图G的拓扑排序序列:1
图中有环,拓扑排序失败
顶点1到顶点1的最短路径是:权值 = 0,顶点序列 =
顶点1到顶点2的最短路径是:权值 = 15,顶点序列 = 1 3 2
顶点1到顶点3的最短路径是:权值 = 5,顶点序列 = 1 3
顶点1到顶点4的最短路径是:权值 = 55,顶点序列 = 1 3 2 4
Sample Input4
8
9
1 2 3 4 5 6 7 8
1 2 10
1 3 20
2 4 30
3 6 40
3 7 50
4 8 60
5 2 70
5 8 80
6 7 90
1
Sample Output4
无向图G的邻接表形式:
1-->3(20)-->2(10)
2-->4(30)
3-->7(50)-->6(40)
4-->8(60)
5-->8(80)-->2(70)
6-->7(90)
7
8
图G的广度优先搜索序列为:1 3 2 7 6 4 8 5
图G的拓扑排序序列:5 1 2 4 8 3 6 7
拓扑排序成功
顶点1到顶点1的最短路径是:权值 = 0,顶点序列 =
顶点1到顶点2的最短路径是:权值 = 10,顶点序列 = 1 2
顶点1到顶点3的最短路径是:权值 = 20,顶点序列 = 1 3
顶点1到顶点4的最短路径是:权值 = 40,顶点序列 = 1 2 4
顶点1到顶点5的最短路径是:权值 = 1000,顶点序列 =(注释:1000是程序里面定义的无穷大)
顶点1到顶点6的最短路径是:权值 = 60,顶点序列 = 1 3 6
顶点1到顶点7的最短路径是:权值 = 70,顶点序列 = 1 3 7
顶点1到顶点8的最短路径是:权值 = 100,顶点序列 = 1 2 4 8
以上是代码设计输入和输出的要求与格式
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#include <stddef.h>
#define TRUE 1
#define FALSE 0
#define OK 1
#define ERROR 0
#define INFEASIBLE -1
#define OVERFLOW -2
#define LIST_INIT_SIZE 100
#define STACK_INIT_SIZE 100
typedef int Status;
#define MAX_VERTEX_NUM 20
typedef enum {DG,DN,AG,AN} GraphKind;//有向图、有向网、无向图、无向网
typedef struct ArcNode{
int adjvex; //该弧头的位置
struct ArcNode *nextarc; //下一条出弧(弧尾相同的下一条弧)
int info; //附加信息
}ArcNode;//弧结点
typedef int VertexType ;
typedef struct VNode{
VertexType data; //顶点信息
ArcNode *firstarc; //第一条出弧
}VNode, AdjList[MAX_VERTEX_NUM];//邻接表头指针向量(顶点数组)
typedef struct {
AdjList vertices; //邻接表头指针向量
int vexnum,arcnum; //顶点数目和弧的数目
GraphKind kind; //图的种类
}ALGraph;
#define MAXQSIZE 100
typedef int QueueElem ;
typedef struct {
QueueElem *base;
int front,rear;} SqQueue; //定义循环队列,存储Glist类型指针
void InitQueue(SqQueue &Q)
{ Q.base = (QueueElem *)malloc(MAXQSIZE * sizeof(QueueElem));
Q.front = Q.rear = 0;
}
Status EnQueue(SqQueue &Q, QueueElem e)
{ if((Q.rear + 1) % MAXQSIZE == Q.front) return ERROR; //队满
Q.base[Q.rear] = e;
Q.rear = (Q.rear + 1) % MAXQSIZE;
return OK;
}
Status DeQueue(SqQueue &Q, QueueElem &e)
{ if(Q.rear == Q.front) return ERROR; //队空
e = Q.base[Q.front];
Q.front = (Q.front + 1) % MAXQSIZE;
return OK;
}
Status QueueEmpty(SqQueue Q)
{
}
typedef int SElemType;
typedef struct {
SElemType *base;
SElemType *top;
int stacksize;
}Stack;
Status InitStack(Stack &s)
{
s.base = (SElemType *)malloc(STACK_INIT_SIZE * sizeof(SElemType));
if(!s.base) exit(OVERFLOW);
s.stacksize = STACK_INIT_SIZE;
s.top = s.base;
return OK;
}//InitStack
Status Push(Stack &s, SElemType x)
{
if(s.top - s.base >= s.stacksize ) return OVERFLOW;
*s.top++ = x;
return OK;
}//push
Status Pop(Stack &s, SElemType &x)
{
if(s.top == s.base ) return ERROR;
x = *(--s.top);
return OK;
}//pop
Status StackEmpty(Stack s)
{
}
//返回顶点u在图中的位置,未找到返回-1
int LocateVex(ALGraph G,VertexType u)
{ int i;
for(i = 0; i < G.vexnum; i++)
if(G.vertices[i].data == u) return i;
return -1;
}
//创建有向图
void CreateDG(ALGraph &G)
{ int i,j,k,info;
VertexType v1,v2;
ArcNode * p;
// printf("\n下面分步输入创建有向图的信息:");
G.kind = DG;
// printf("\n1.请输入图的顶点个数:");
scanf("%d", &G.vexnum);
// printf("\n2.请输入图的弧的个数:");
scanf("%d", &G.arcnum);
// printf("\n3.请连续输入%d个顶点(整型):",G.vexnum);
for(k = 0; k < G.vexnum; k++) //邻接表头指针向量初始化
{ scanf("%d", &G.vertices[k].data);
G.vertices[k].firstarc = NULL;
}
for(k = 0; k < G.arcnum; k++) //建立弧结点<v,w>
{
// printf("\n建立弧%d,请输入弧的信息,格式为v w info:",k+1);
scanf("%d %d %d", &v1, &v2, &info);
i = LocateVex(G,v1); j = LocateVex(G,v2); //确定v1,v2在图中的位置
if(i == -1 || j == -1)
{ printf("\n输入弧信息非法,程序退出!"); break; }
p = (ArcNode *) malloc( sizeof(ArcNode) );
p->adjvex = j;
p->info = info;
p->nextarc = G.vertices[i].firstarc;
G.vertices[i].firstarc = p;
}
}
//按邻接表的形式输出无向图
void PrintDG(ALGraph G)
{ ArcNode *p;
printf("\n无向图G的邻接表形式:");
printf("\n");
}
void BFSTraverse(ALGraph G)
{ int i,v,visited[MAX_VERTEX_NUM];
SqQueue Q;
ArcNode *p;
InitQueue(Q); //初始化队列
for(v = 0; v < G.vexnum; v++) visited[v] = FALSE; //初始化顶点访问标志
//如果是联通图,此循环只执行一次
for(i = 0; i < G.vexnum; i++)
{ if(visited[i]) continue; //若v访问过,从下一顶点开始继续广度遍历
visited[i] = TRUE;
printf("%d ",G.vertices[i].data);
EnQueue(Q,i);
while(!QueueEmpty(Q))
{
}//while
}//for
}
//对邻接表存储结构的有向图进行拓扑排序
//若G无回路,则输出G的顶点的一个拓扑序列,返回OK,否则返回ERROR
Status TopologicSort(ALGraph G)
{ int indegree[MAX_VERTEX_NUM]; //存放每个顶点的入度
int i;
ArcNode *p;
Stack S;
int count = 0; //对输出顶点计数
for(i = 0; i < G.vexnum; i++) //indegree初始化赋值
{ indegree[i] = 0;
}
}
//用Dijkstra算法求有向网G的v0顶点到其余顶点v的最短路径P[v]及其带权路径长度D[v]
//若P[v][w]为真,则w是从v0到v的最短路径上的顶点,
//也即P[v]存放的是v->v0最短路径上的顶点,D[v]存放的是该最短路径的长度
//final[v]为真,表明已经求得v0->v的最短路径
typedef int PathMatrix[MAX_VERTEX_NUM][MAX_VERTEX_NUM];
typedef int ShortPathTable[MAX_VERTEX_NUM];
#define INFINITY 1000 //无穷大
//求邻接表中顶点v到顶点w的权值
int GetInfo(ALGraph G, int v, int w)
{ ArcNode *p;
p = G.vertices[v].firstarc;
while(p)
{ if(p->adjvex == w) return p->info;
p = p->nextarc;
}
return INFINITY;
}
void ShortestPath_DIJ(ALGraph G,VertexType u, PathMatrix &P, ShortPathTable &D)
{ int final[MAX_VERTEX_NUM];
int v0 = LocateVex(G,u),v,w,i,min;
for(v = 0; v < G.vexnum; v++)
{ final[v] = 0;
for(w = 0; w < G.vexnum; w++) P[v][w] = 0;
D[v] = GetInfo(G,v0,v); //v的最短路径的长度
if (D[v] < INFINITY)
{ P[v][v0] = 1; //v的最短路径是v0->v
P[v][v] = 1;
}
}//for
D[v0] = 0; final[v0] = 1;
}
void PrintShortPath(ALGraph G,VertexType u, PathMatrix P, ShortPathTable D)
{
for(int v = 0; v < G.vexnum; v++)
{
}
}
int main()
{ ALGraph G;
int v0;
CreateDG(G);
PrintDG(G);
printf("图G的广度优先搜索序列为:");
BFSTraverse(G);
printf("\n");
if (TopologicSort(G ) == OK) printf("\n拓扑排序成功");
else printf("\n图中有环,拓扑排序失败");
printf("\n");
// printf("请输入最短路径的源点:");
scanf("%d", &v0);
PathMatrix P;
ShortPathTable D;
ShortestPath_DIJ(G,v0,P,D);
PrintShortPath(G,v0,P,D);
}
根据上面的要求和代码上的标注补全这个代码,注意以给出的代码不可以修改,只能补充函数内有空行的代码。使它的输入与输出和示例一样
最新发布