拓扑排序算法与数据结构课程设计Word下载.docx

上传人:b****3 文档编号:17405406 上传时间:2022-12-01 格式:DOCX 页数:20 大小:174.40KB
下载 相关 举报
拓扑排序算法与数据结构课程设计Word下载.docx_第1页
第1页 / 共20页
拓扑排序算法与数据结构课程设计Word下载.docx_第2页
第2页 / 共20页
拓扑排序算法与数据结构课程设计Word下载.docx_第3页
第3页 / 共20页
拓扑排序算法与数据结构课程设计Word下载.docx_第4页
第4页 / 共20页
拓扑排序算法与数据结构课程设计Word下载.docx_第5页
第5页 / 共20页
点击查看更多>>
下载资源
资源描述

拓扑排序算法与数据结构课程设计Word下载.docx

《拓扑排序算法与数据结构课程设计Word下载.docx》由会员分享,可在线阅读,更多相关《拓扑排序算法与数据结构课程设计Word下载.docx(20页珍藏版)》请在冰豆网上搜索。

拓扑排序算法与数据结构课程设计Word下载.docx

//该弧所指向的顶点在数组中的位置

structArcNode*next;

//指向当前起点的下一条弧的指针

}ArcNode;

typedefstructVNode//头结点

{VertexTypename;

intindegree;

//顶点入度

ArcNode*firstarc;

//指向当前顶点的第一条弧的指针

}VNode,AdjList[MAX_VERTEX_NUM];

{AdjListvexhead;

//邻接表头结点数组

intvexnum,arcnum;

//图的顶点数和弧数

}ALGraph;

五、模块划分

1、链式队列操作

1)voidInitQueue(LinkQueue*Q)

功能:

初始化链式队列

参数:

*Q待初始化的队列

2)intQueueEmpty(LinkQueueQ)

判断空队列

Q待判断的队列

返回值:

队列为空返回1;

队列非空返回0

3)voidEnQueue(LinkQueue*Q,ElemTypee)

元素入队列

*Q待操作的队列;

e要入队列的元素

4)voidDeQueue(LinkQueue*Q,ElemType*e)

元素出队列

*e记录出队列元素的变量

2、有向图(DAG)邻接表存储结构(ALG)的操作

1)intLocateVex(ALGraphG,VertexTypev)

顶点在头结点数组中的定位

G待操作的图;

v要在图中定位的顶点

顶点存在则返回在头结点数组中的下标;

否则返回图的顶点数

2)intCreateGraph(ALGraph*G)

建立图

函数内包含了由用户输入顶点数、弧数、顶点以及弧的操作

*G待操作的图

图建立成功返回1;

图建立失败返回0

错误判断:

包含顶点数、弧数是否正确的判断;

包含用户输入的弧的顶点是否存在的判断

3)voidPrintGraph(ALGraphG)

输出有向图

G待输出的图

4)intCreateGraph2(ALGraph*G)

建立预置课程图(输出函数内预置课程信息,并自动建立有向图)

包含顶点数、弧数是否正确的判断

包含弧的顶点是否存在的判断

5)voidPrintGraph2(ALGraphG)

输出预置课程图

3、拓扑排序及拓扑检测算法

1)voidTopologicalSort(ALGraphG)

实现拓扑排序

G待进行拓扑排序的图

包含有向图是否有环的判断

2)voidTopSortCheck(ALGraphG)

运用拓扑排序的思想检测教学计划

函数内包含了由用户输入待检测的课程序列的操作

G待操作的图

包含用户输入的课程是否存在的判断

包含不是拓扑序列的原因(该课程有多少个先决课程未学)

4、主函数

voidmain()

主函数

利用while语句和switch语句实现菜单化调用函数

六、源程序

#include"

stdlib.h"

stdio.h"

string.h"

/*******************************************/

/*以下为链式队列操作*/

/*定义链式队列类型*/

structQNode*next;

QueuePtrrear;

/*1.初始化链式队列*/

voidInitQueue(LinkQueue*Q)

{Q->

front=Q->

rear=(QueuePtr)malloc(sizeof(QNode));

if(!

(Q->

front))exit(0);

Q->

front->

next=NULL;

}

/*2.判断空队列*/

intQueueEmpty(LinkQueueQ)

{if(Q.front==Q.rear)

return1;

else

return0;

/*3.入队列*/

voidEnQueue(LinkQueue*Q,ElemTypee)

{QueuePtrp;

p=(QueuePtr)malloc(sizeof(QNode));

p)exit(0);

p->

data=e;

rear->

next=p;

rear=p;

/*4.出队列*/

voidDeQueue(LinkQueue*Q,ElemType*e)

if(Q->

front!

=Q->

rear)

{p=Q->

next;

*e=p->

data;

Q->

next=p->

if(Q->

rear==p)Q->

rear=Q->

front;

free(p);

}

/****************************************************/

/*以下为有向图(DAG)邻接表存储结构(ALG)的操作*/

#defineMAX_VERTEX_NUM20//最大顶点个数

//顶点信息(名称)

/*图的类型定义(邻接表存储结构)*/

typedefstructArcNode//链表结点

//该弧所指向的顶点在数组中的位置

//指向当前起点的下一条弧的指针

typedefstructVNode//头结点

//顶点入度

//指向当前顶点的第一条弧的指针

//邻接表头结点数组

//图的顶点数和弧数

/*5.顶点在头结点数组中的定位*/

intLocateVex(ALGraphG,VertexTypev)

{inti;

for(i=0;

i<

G.vexnum;

i++)

if(strcmp(v,G.vexhead[i].name)==0)break;

returni;

/*6.建立图(邻接表)*/

intCreateGraph(ALGraph*G)//成功建立返回1,不成功则返回0

{inti,j,k;

VertexTypev1,v2;

ArcNode*newarc;

printf("

\n输入有向图顶点数和弧数vexnum,arcnum:

"

);

//输入顶点数和弧数

scanf("

%d,%d"

&

(*G).vexnum,&

(*G).arcnum);

//输入并判断顶点数和弧数是否正确

if((*G).vexnum<

0||(*G).arcnum<

0||(*G).arcnum>

(*G).vexnum*((*G).vexnum-1))

{printf("

\n顶点数或弧数不正确,有向图建立失败!

\n"

return0;

\n输入%d个顶点:

(*G).vexnum);

//输入顶点名称

(*G).vexnum;

{scanf("

%s"

(*G).vexhead[i].name);

\n顶点列表:

\n共有%d个顶点:

"

//输出顶点名称

printf("

%s"

i++)//邻接表初始化

{(*G).vexhead[i].firstarc=NULL;

(*G).vexhead[i].indegree=0;

\n\n输入%d条边:

vivj\n"

(*G).arcnum);

//输入有向图的边

for(k=0;

k<

(*G).arcnum;

k++)

%s%s"

v1,v2);

//v1是弧的起点(先决条件),v2是弧的终点

i=LocateVex(*G,v1);

j=LocateVex(*G,v2);

//定位顶点并判断顶点是否存在

if(i>

=(*G).vexnum)

{printf("

顶点%s不存在,有向图建立失败!

v1);

}if(j>

v2);

newarc=(ArcNode*)malloc(sizeof(ArcNode));

//前插法建顶点链表

newarc->

vexpos=j;

if((*G).vexhead[i].firstarc==NULL)

{newarc->

(*G).vexhead[i].firstarc=newarc;

else

next=(*G).vexhead[i].firstarc->

(*G).vexhead[i].firstarc->

next=newarc;

(*G).vexhead[j].indegree++;

//对应顶点入度计数加1

}

\n有向图建立成功!

return1;

/*7.按邻接表方式输出有向图*/

voidPrintGraph(ALGraphG)

ArcNode*p;

\n输出有向图:

i<

i++)

\n顶点:

G.vexhead[i].name);

printf("

入度:

%3d\n"

G.vexhead[i].indegree);

p=G.vexhead[i].firstarc;

邻接点:

while(p!

=NULL)

G.vexhead[p->

vexpos].name);

p=p->

//为避免演示时要输入过多数据,以下函数将课程编号、课程间的先后关系通过数组预置

/*8.建立预置课程图(邻接表)*/

intCreateGraph2(ALGraph*G)//成功建立返回1,不成功则返回0

ArcNode*newarc;

VertexTypeSubjectName[12]={"

C1"

"

C2"

C3"

C4"

//课程名称

C5"

C6"

C7"

C8"

C9"

C10"

C11"

C12"

},

RelationV1[16]={"

//基础课

},

RelationV2[16]={"

//以上面课程为基础的课

};

/*输出本程序使用的课程及先后关系表*/

\n本程序预置了如下课程及先后关系:

\n课程编号课程名称先决条件\n\

C1程序设计基础无\n\

C2离散数学C1\n\

C3数据结构C1,C2\n\

C4汇编语言C1\n\

C5语言的设计和分析C3,C4\n\

C6计算机原理C11\n\

C7编译原理C5,C3\n\

C8操作系统C3,C6\n\

C9高等数学无\n\

C10线性代数C9\n\

C11普通物理C9\n\

C12数值分析C9,C10,C1\n"

system("

PAUSE"

(*G).vexnum=12;

(*G).arcnum=16;

\n课程数或先后关系不正确,有向图建立失败!

return0;

}//判断课程数和弧数是否正确

{strcpy((*G).vexhead[i].name,SubjectName[i]);

{strcpy(v1,RelationV1[k]);

strcpy(v2,RelationV2[k]);

//定位课程并判断课程是否存在

课程%s不存在,有向图建立失败!

if(j>

//前插法建课程链表

//对应课程入度计数加1

/*9.按邻接表方式输出预置课程图*/

voidPrintGraph2(ALGraphG)

\n课程:

以本课程为基础的课程:

}

/**********************************/

/*以下为拓扑排序算法*/

/*10.拓扑排序*/

voidTopologicalSort(ALGraphG)

{inti,k,count;

ElemTypee;

LinkQueueQ;

/*定义队列*/

InitQueue(&

Q);

i++)//零入度课程入队列

if(!

G.vexhead[i].indegree)EnQueue(&

Q,i);

count=0;

//对输出课程计数变量初始化

\n\n\n以上课程的一个拓扑排序序列为:

while(!

QueueEmpty(Q))

{DeQueue(&

Q,&

e);

//先将入度为零的课程输出

G.vexhead[e].name);

count++;

//对输出的顶点计数

for(p=G.vexhead[e].firstarc;

p;

p=p->

next)//遍历当前课程的邻接点

{k=p->

vexpos;

//邻接点位置

if(!

(--G.vexhead[k].indegree))//每个邻接点入度减1后若为零则入队列

EnQueue(&

Q,k);

if(count<

G.vexnum)

\n该有向图有回路,无法完成拓扑排序!

/*以下为拓扑检测算法*/

/*11.运用拓扑排序的思想检测教学计划*/

voidTopSortCheck(ALGraphG)

{inti,k;

ArcNode*p;

VertexTypev,CheckList[12];

//待检测序列

TopologicalSort(G);

\n输入待检测的课程序列:

i++)//输入待检测序列

scanf("

CheckList[i]);

{strcpy(v,CheckList[i]);

k=LocateVex(G,v);

if(k>

=G.vexnum)//判断课程是否存在

课程%s不存在!

v);

return;

if(G.vexhead[k].indegree!

=0)//判断课程入度是否为零

{printf("

学习课程%s时,还有%d门先决课程未学!

v,G.vexhead[k].indegree);

本课程序列不是拓扑序列\n\n"

else

{for(p=G.vexhead[LocateVex(G,v)].firstarc;

next)//遍历此课程邻接点

{k=p->

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 解决方案 > 学习计划

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1