数据结构:教学计划的编制问题(实验10实验报告)由刀豆文库小编整理,希望给你工作、学习、生活带来方便,猜你可能喜欢“数据结构图的实验报告”。
数据结构实验报告
实验十:教学计划的编制问题
姓名:戴铁泉 学号:20101410305 班级:物联网1001班 完成日期:2012.05.21
一、问题描述:
若用有向网表示教学计划,其中顶点表示某门课程,有向边表示课程之间的先修关系(如果A课程是B课程的先修课程,那么A到B之间有一条有向边从A指向B)。试设计一个教学计划编制程序,获取一个不冲突的线性的课程教学流程。(课程线性排列,每门课上课时其先修课程已经被安排)。基本要求
(1)输入参数:课程总数,每门课的课程号(固定占3位的字母数字串)和直接先修课的课程号。
(2)若根据输入条件问题无解,则报告适当的信息;否则将教学计划输出到用户指定的文件中。
二.需求分析:
1、本程序需要基于图的基本操作来实现
三.概要设计
抽象数据类型:
为实现上述功能需建立一个结点类,线性表类,图类。算法的基本思想:
1、图的构建:
建立一个结点类,类的元素有字符型变量用来存储字母,整形变量用来存储位置,该类型的指针,指向下一个元素。建立一个线性表类,完成线性表的构建。建立一个图类,完成图的信息的读取,(如有n个点,则建立n个线性表,将每个结点与其指向的结点组成一个线性表,并记录线性表的长度)。
2、Topsort算法:
先计算每个点的入度,保存在数组中。找到第一个入度为0 的点,将该点所连的各点的入度减一。再在这些点中找入度为0 的点。如果找到,重复上述操作。如果找不到,则跳出while循环,再搜索其他的点,看入度是否为0。再重复上述操作,如果所有的入度为0的点都被寻找到,但个数少于输入顶点的个数,说明该图存在环。程序的流程:
(1)输入模块: 读入图的信息(顶点和边,用线性表进行存储)。(2)处理模块:topsort算法。(3)输出模块:将结果输出。
四.详细设计:
算法的具体步骤: cla Node{//结点类 public:
string node;
int position;//位置
Node* next;
bool visit;//是否被访问
Node(){visit=false;next=NULL;position=0;node=' ';} };cla Line{
//线性表类 public: int num;Node* head;Node* rear;Node* fence;Line(){num=0;head=fence=rear=new Node();}
void insert(int v,string ch){
//插入元素
} Node* current=new Node();current->node=ch;current->position=v;fence->next=current;fence=current;num++;};cla Graph{
//图类 private: int numVertex;int numEdge;Line* line;public: Graph(int v,int e){numVertex=v;numEdge=e;line =new Line[v];} void pushVertex(){ //读入点
} void pushEdge(){ //读入边
string ch1,ch2;int pos1,pos2;for(int i=0;i
} cout>ch;line[i].head->node=ch;line[i].head->position=i;
}
} cout>ch1>>ch2;for(int j=0;j
} line[pos1].insert(pos2,ch2);if(line[j].head->node==ch1)pos1=j;
//找到该字母对应的位置
if(line[j].head->node==ch2){
} pos2=line[j].head->position;break;
void topsort(){
//拓扑排序
int i;int *d=new int[numVertex];
for(i=0;i
//数组初始化
for(i=0;i
Node* p=line[i].head;while(p->next!=NULL){ d[p->next->position]++;//计算每个点的入度
}
p=p->next;} int top=-1,m=0,j,k;
for(i=0;i
} while(top!=-1){ if(d[i]==0){ d[i]=top;
//找到第一个入度为0的点
top=i;
j=top;
top=d[top];
coutnode
m++;
Node* p=line[j].head;
while(p->next!=NULL){
k=p->next->position;
d[k]--;
//当起点被删除,时后面的点的入度-1
if(d[k]==0){
d[k]=top;
top=k;
}
p=p->next;
}
} }
cout
if(m
//输出点的个数小于输入点的个数,不能完全遍历
cout
delete []d;} };int main(){
int n,m;cout>n>>m;Graph G(n,m);
G.pushVertex();G.pushEdge();G.topsort();system(“pause”);
return 0;} 五.调试分析:
将建立的线性表输出来检验图的信息是否完全被读入,构建是否正确。
六.测试结果:
七.实验心得:
1、本实验是在图的遍历问题的基础上做的,图的构建大部分是采用图的遍历问题中的代码(不过要将结点类中的char改为string型),自己另外写了topsort函数,就完成了整个程序。
2、topsort函数中一开始采用的方法是找到一个入度为0的点,完成 相应的操作后,重新进行搜索,后来改进代码,先搜索入度为0的 点后面连接的点,这样减少了算法复杂度。
八、附件
教学计划的编制问题.cpp #include #include using namespace std;cla Node{//结点类 public:
string node;
int position;//位置
Node* next;
bool visit;//是否被访问
Node(){visit=false;next=NULL;position=0;node=' ';} };cla Line{
//线性表类 public:
int num;Node* head;Node* rear;Node* fence;Line(){num=0;head=fence=rear=new Node();}
void insert(int v,string ch){
//插入元素
Node* current=new Node();current->node=ch;current->position=v;
};
} fence->next=current;fence=current;num++;cla Graph{
//图类 private:
int numVertex;int numEdge;Line* line;public:
Graph(int v,int e){numVertex=v;numEdge=e;line =new Line[v];} void pushVertex(){ //读入点
} void pushEdge(){ //读入边 string ch;for(int i=0;i
} cout>ch;line[i].head->node=ch;line[i].head->position=i;
} string ch1,ch2;int pos1,pos2;for(int i=0;i
} cout>ch1>>ch2;for(int j=0;j
} line[pos1].insert(pos2,ch2);if(line[j].head->node==ch1)pos1=j;
//找到该字母对应的位置
if(line[j].head->node==ch2){
} pos2=line[j].head->position;break;
void topsort(){
//拓扑排序
int i;int *d=new int[numVertex];
for(i=0;i
//数组初始化
for(i=0;i
} Node* p=line[i].head;while(p->next!=NULL){ d[p->next->position]++;//计算每个点的入度
p=p->next;} int top=-1,m=0,j,k;
for(i=0;i
} while(top!=-1){ if(d[i]==0){ d[i]=top;
//找到第一个入度为0的点
top=i;
j=top;
top=d[top];
coutnode
m++;
Node* p=line[j].head;
while(p->next!=NULL){
k=p->next->position;
d[k]--;
//当起点被删除,时后面的点的入度-1
if(d[k]==0){
d[k]=top;
top=k;
}
p=p->next;
}
} }
cout
//输出点的个数小于输入点的个数,不能完全遍历
cout
delete []d;} };int main(){
int n,m;cout>n>>m;Graph G(n,m);G.pushVertex();
G.pushEdge();G.topsort();system(“pause”);
return 0;}