数据结构实验五教学计划编制课案Word下载.docx

上传人:b****6 文档编号:18809025 上传时间:2023-01-01 格式:DOCX 页数:20 大小:80.98KB
下载 相关 举报
数据结构实验五教学计划编制课案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

①.正常的输入

输入:

输入课程总数:

3

请输入课程1的名称:

小学数学

请输入课程2的名称:

初中数学

请输入课程3的名称:

大学数学

小学数学是否有先修(1/0):

初中数学是否有先修(1/0):

1

请输入先修课程的名称:

高中数学是否有先修(1/0):

输出:

小学数学初中数学高中数学

②.正常的输入

4

2

请输入课程4的名称:

1是否有先修(1/0):

2是否有先修(1/0):

3是否有先修(1/0):

4是否有先修(1/0):

4132

③.有两个先修课程的情况

A

B

C

D

A是否有先修(1/0):

B是否有先修(1/0):

C是否有先修(1/0):

D是否有先修(1/0):

ABCD

④.有三个先修课程的情况

DABC

⑤.所有课程无先修

123

二、概要设计

1.抽象数据类型

题设要求使用一个有向图表示教学计划,顶点表示某门课程,有向边表示课程之间的先修关系,数据的对象是图中的每一个顶点和有向边。

由此为本问题确定一个图的数据关系。

本题目需要一个数据结构来储存遍历过的图的结点,该数据结构满足先进先出,所以用队列来实现。

2.ADT

ADTEdge{

数据对象:

N(边的名称)V(标记)F(先修课结点)

数据关系:

(N&

&

V&

F)∈R

(R1&

R2&

Rn)∈Graph

基本操作:

stringgetVal(intv)//返回边的名称

intgetMark(intv)//返回标记

voidsetVal(intv,stringval)//设边的名称

voidsetMark(intv,intMark)//设置标记

voidsetfirst(intv)//设置先修结点标记

}

ADTGraph{

V,R(分别代表某门课程的顶点组成的一个顶点集 

和代表课程先修关系的有向弧边组成的一个弧集 

R。

VR={<

v,w>

|v,w∈V且P(v,w)}

<

表示从v到w的一条弧,并称v为弧头,w为弧尾。

intn();

//返回图中的顶点数

intfirst(int);

//返回该点的第一条邻边

intnext(int);

//返回该店的下一条邻边

voidsetEdge(int,int,int);

//为有向边设置权值

voidFind(stringsearch,int&

v)

intn()

ADTqueue{

前指针front,后指针rear

R={<

ai-1,ai>

|ai-1,ai∈car,i=1,2,3….n}

约定a1为队列头,an为队列尾。

queue();

//队列结构初始化

~queue();

//结构销毁操作

boolpush(constint&

it);

//数据入列

boolpop(int&

//数据出列

intsize();

//获取队列长度}

3.算法的基本思想

①.通过用户输入的顶点的个数(课程数)初始化一个表示有向图的相邻矩阵,初始化边的访问次数全部设置为零,通过输入边的信息和先修关系,设置先修关系的计数器,记录每条边先修关系的数量,完成对有项图的构建。

②.将先修关系为零的边放入队列,然后开始处理队列。

当从队列中删除一个顶点时,把它打印出来,同时将其所有相邻顶点的先修关系计数器减一。

当某个相邻顶点的计数器为0时,就将其放入队列。

如果还有顶点未被打印,而队列已经为空,则图中必然包含回路(既不可能不违反先决条件完成任务)。

4.程序的流程

(1)初始化模块:

输入课程总数,再输入相应数量的课程编号及每个课程的先修课程,用这些信息初始化一个有向图。

(2)拓扑排序模块:

对有向图进行拓扑排序。

(3)输出模块:

根据有向图是否为空输出。

为空时,输出拓扑排序结果;

不为空时输出输入错误提示。

三、详细设计

1.物理数据类型

用户输入的课程个数不定,所以存储拓扑排序后的顶点的个数不定,对于图有两种存储方式,本题中用邻接矩阵来存储图的信息,对于边很少的图来说,虽然用邻接矩阵有些浪费空间,但是题目做起来相对方便。

由于用户输入的课程个数不定,使用链式栈。

使用string类型储存用户信息和边的信息。

2.算法的具体步骤

初始化一个有向图——先修信息的储存——拓扑排序与输出

①.初始化一个有向图:

包括初始化被访问标记和先修标记,动态创建二维数组和用于储存边信息的一维数组。

Graph(intnumVert)

{

inti,j;

numVertex=numVert;

numEdge=0;

mark=newPoint[numVert];

//Initializemarkarray

for(i=0;

i<

numVertex;

i++)

{

mark[i].visit=-1;

//包括初始化被访问标记和先修标记

mark[i].first=0;

}

matrix=(int**)newint*[numVertex];

//Makematrix

matrix[i]=newint[numVertex];

i++)//Edgesstartw/0weight

for(intj=0;

j<

j++)matrix[i][j]=0;

}

②.先修信息的存储:

由用户输入是否有先修课程后,用户每输入一个先修课程,就将这个课程对应的先修标记加1.

cout<

a.getVal(i)<

"

是否有先修(1/0)"

;

cin>

>

judge;

if(judge)

{

a.setfirst(i);

cout<

请输入先修课程的名称:

"

cin>

Ch1;

a.Find(Ch1,v1);

a.setEdge(v1,i,10);

}

voidsetfirst(intv)

mark[v].first++;

③.拓扑排序与输出:

定义两个队列A和B,将先修关系为零的边放入队列A,然后开始处理队列。

当从队列A中删除一个顶点时,该顶点进入B队列,再把该顶点打印出来,同时将其所有相邻顶点的先修关系计数器减一。

重复将队列B中首元素输出并删除,直到队列为空,就是课程表的排序。

voidDFS(Graph*G,queue<

int>

*Q,queue<

*L)

for(intv=0;

v<

n();

v++)

if(mark[v].first==0)

Q->

push(v);

setMark(v,1);

while(Q->

size()!

=0)

inti=Q->

front();

//获取Q栈首元素

pop();

//弹出Q栈

L->

push(i);

//进L栈

for(intw=first(i);

w<

w=next(i,w))

mark[w].first--;

if(mark[w].first==0)

{

Q->

push(w);

setMark(w,1);

}

for(inti=0;

if(getMark(i)==-1)//为0时表示还未被删除,图不为空

课程输入错误!

<

endl;

exit(0);

3.算法的时空分析及改进设想

因为图的邻接矩阵是一个|V|×

|V|矩阵,所以邻接矩阵的空间代价为Θ(|V|^2),对于有n个顶点的和E条弧的有向图而言,对此图的拓扑排序算法时间复杂度为Θ(V+E)

4.输入和输出的格式

1.输入课程数n

cout<

请输入课程总数:

cin>

n;

if(n<

cout<

输入错误重新输入(大于零的整数)"

2.输入每门课的课程编号

for(inti=0;

请输入课程"

i+1<

名称:

Ch;

a.setVal(i,Ch);

3.获得先修的课程编号

judge=0;

1.编制成功,把队列S中的顶点序列输出。

cout<

课程表的排序为:

a.DFS(&

a,&

Q,&

L);

intj=L.front();

a.getVal(j)<

L.pop();

2.编制失败,图中有回路,输出错误信息,结束程序。

if(G.getMark(i)==0)//为0时表示该顶点未经过拓扑排序

{

cout<

endl;

exit(0);

四.调试分析

DFS问题,书上思路很明确并且有很多源码,没有大的问题。

五.测试结果

1.正常的输入输出

3.有两个先修课程的情况

附录

#include<

iostream>

queue>

fstream>

string>

iomanip>

usingnamespacestd;

classPoint

public:

stringLessonName;

intvisit;

intfirst;

//1有先修,0无

};

classGraph

{//Implementadjacencymatrix

private:

intnumVertex,numEdge;

//Storenumberofverticesedges

int**matrix;

//Pointertoadjacencymatrix

Point*mark;

//Pointertomarkarray

Graph(intnumVert)

{//Makegraphw/numVertvertices

~Graph()

delete[]mark;

delete[]matrix[i];

delete[]matrix;

returnnumVertex;

inte()

returnnumEdge;

intfirst(intv)

{//Returnv'

sfirstneighbor

inti;

if(matrix[v][i]!

=0&

mark[i].visit==-1)returni;

returni;

//Returnnifnone

intnext(intv1,intv2)

//Getv1'

sneighborafterv2

for(i=v2+1;

if(matrix[v1][i]!

mark[i].visit==-1)

//cout<

此时next的i值是:

v1+1<

i+1<

returni;

//Setedge(v1,v2)towgt

voidsetEdge(intv1,intv2,intwgt)

numEdge++;

//ERROR

matrix[v1][v2]=wgt;

voiddelEdge(intv1,intv2)

{//Deleteedge(v1,v2)

if(matrix[v1][v2]!

numEdge--;

matrix[v1][v2]=0;

intweight(intv1,intv2)

returnmatrix[v1][v2];

stringgetVal(intv)

returnmark[v].LessonName;

intgetMark(intv)

returnmark[v].visit;

voidsetVal(intv,stringval)

mark[v].LessonName=val;

voidsetMark(intv,intMark)

mark[v].visit=Mark;

if(mark[i].LessonName==search)

v=i;

return;

路径错误"

return;

voidDFS(Graph*G,queue<

intmain()

intn;

intv1;

intv2;

intjudge;

stringCh;

stringCh1;

stringCh2;

queue<

Q;

L;

intD[100];

intcount=0;

if(n<

Grapha(n);

system("

pause"

);

return0;

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

当前位置:首页 > 经管营销

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

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