数据结构课程设计个人任务(一共8道题)
对于顺序存储的线性表(假定顺序表非空),使用vector或数组,实现直接插入排序算法,并输出每趟的排序结果。
参考函数原型:(vector版本)
//直接插入排序
template
void SimpleInsertSort( vector &A );
输入说明 :
第一行:顺序表A的数据元素的数据类型标记(0:int,1:double,2:char,3:string)
第二行:待排序顺序表A的数据元素(数据元素之间以空格分隔)
输出说明 :
如第一行输入值为0、1、2、3之外的值,直接输出“err”
否则:
第一行:第一趟的排序结果
第三行:第二趟的排序结果
…
第n行:最终的排序结果
输入范例 :
0
21 25 49 25 16 8
输出范例 :
21 25 49 25 16 8
21 25 49 25 16 8
21 25 25 49 16 8
16 21 25 25 49 8
8 16 21 25 25 49
需要代做加qq1975728171
数据结构课程设计小组任务(一共10道题)
目的:设计并实现一个算法Schedule,完成简单的操作系统任务调度问题。
描述:操作系统任务分为系统
任务和用户任务两种。其中,系统任务的优先级 < 50,用户任务的优先级 >= 50且 <= 255。优先级大于255的为非法任务,应予以剔除。现有一任务序列task(顺序存储),任务数为n。每个task的元素值表示任务的优先级,数值越小,优先级越高。算法scheduler实现如下功能,将task中的任务按照系统任务、用户任务依次存放到队列 system_task和 user_task中(队列中元素的值是任务在顺序表task中对应的下标),并且优先级高的任务排在前面。优先级相同的任务按照在task中的相对顺序入队排列(即task序列中在先的任务排在前面)。
要求:顺序表使用vector或数组,队列使用本学期设计好的顺序队列ADT
参考函数原形:
template
void Schedule(vector &A, SqQueue &system_task, SqQueue &user_task);
输入说明 :
第一行:任务序列task中各个任务的优先级(任务优先级之间以空格分隔)
输出说明 :
第一行:任务序列task的遍历结果,以","分隔
格式: (序号,优先级) ...
空行
第二行:系统任务队列遍历结果,以空格分隔。如系统任务队列为空,输出 none
第三行:用户任务队列遍历结果,以空格分隔。如用户任务队列为空,输出 none
输入范例 :
0 30 155 1 80 300 155 170 40 30 99
输出范例 :
(0,0),(1,30),(2,155),(3,1),(4,80),(5,300),(6,155),(7,170),(8,40),(9,30),(10,99)
0 3 1 9 8
4 10 2 6 7
在使用图的邻接表ADT的基础上,设计一个算法,按照深度优先搜索的思想找出从指定结点出发且长度为m的所有简单路径。并将此算法加入到邻接表ADT中,在邻接表ADT中提供一个公有的成员函数FindPath(start, m)。
提示:
(1)这个问题相当于从指定结点开始深度优先遍历,而且遍历的深度正好为m。为此,在遍历时需要记住遍历的深度,当深度达到m时,就不需要递归了。此时需要输出这条路径,因此在遍历的过程中还需要记住整条路径。
(2)由于深度优先遍历是用递归实现的,所以FindPath函数最好也设计两个。一个是共有的FindPath函数,供用户使用(外壳);另一个是私有的FindPath函数,实现递归的遍历。公有的FingPath函数调用私有的FindPath函数找出这些路径。
(3)在调用递归的FindPath函数前,外壳函数还需要做一些辅助工作:
1)要找的是长度为m的简单路径,因此路径上不能有相同的结点,于是定义了一个数组visited记录结点是否在路径上。
2)当路径长度等于m时要输出这条路径,于是定义了一个数组stack保存这条路径。每访问一个结点,都要把结点记录在stack中。
3)递归的FindPath函数有6个参数。第1个参数是遍历的起点的序号;第2个参数是要求的路径长度;第3个参数是符合要求的路径数目;第4个参数是当前路径中的结点数,当前路径的长度是结点数减1;第5个参数是visited数组,记录结点是否在路径上;第6个参数是一个用于记录路径上结点序号的数组,作用和栈类似。
4)调用FindPath函数时要指出从哪一个结点出发,而递归的FingPath函数的参数是起点的序号。递归的FindPath函数首先将起点放入这条路径,并标记这个结点已被访问,然后判断路径长度是否是m。如果长度已达到m,则输出这条路径,并将最后一个结点从路径上删除,返回上一层调用,检查是否还有其它的途径;否则逐个检查起点的后继结点。如果该后继结点没有被访问过,则对该结点调用递归的FindPath函数继续寻找。在所有的后继都检查后,表示这条路径处理完毕。将起始结点从这条路径上删除,返回上一层调用。
参考函数原型:
(1)//找出从指定结点出发且长度为m的所有简单路径(外壳部分)
template<class TypeOfVer, class TypeOfEdge>
void adjlist_graph<TypeOfVer, TypeOfEdge>::FindPath(int start, int m);
(2)//找出从指定结点出发且长度为m的所有简单路径(递归部分)
template<class TypeOfVer, class TypeOfEdge>
void adjlist_graph<TypeOfVer, TypeOfEdge>::FindPath(int start, int m, int &count, int top, int visited[], int stack[]);
输入说明 :
第一行:图的类型
第二行:结点数
第三行:结点集
第四行:边数
第五行:边集
第六行:起点start
第七行:路径长度m
输出说明 :
第一行:顶点集
第二行:邻接表
空行
如无符合要求的路径:输出 0
否则: 路径输出(一条路径占一行)
路径数目
输入范例 :
DG
8
1 2 3 4 5 6 7 8
8
0 1
0 2
1 3
1 4
2 5
2 6
3 7
4 7
0
2
输出范例 :
1 2 3 4 5 6 7 8
1->2->1
2->4->3
3->6->5
4->7
5->7
6
7
8
1->3->7
1->3->6
1->2->5
1->2->4
4
问题描述 :
在完成小组任务8的基础上,最终完成公有成员函数Get_CriticalPath()的功能。增加获取一条关键路径的功能。该路径仅输出,不须保存。
提示:在AOE网中,
(1)关键活动:开始时间余量为0的活动。即活动的最早开始时间等于它的最迟开始时间。
(2)根据各个顶点的Ve和Vl值,在求得每条弧s的最早开始时间e[s]和最迟开始时间l[s]后,若某条弧满足条件e[s]=l[s],该弧所对应的活动即为关键活动。
(3)关键路径:由关键活动所形成的从源点到汇点的每一条路径。
参考函数原型:
//获取AOE网各顶点事件的最早发生时间ve和最迟发生时间vl、活动ak的最早开始时间e和最迟开始时间l、一条关键路径
template<class TypeOfVer, class TypeOfEdge>
bool adjlist_graph<TypeOfVer, TypeOfEdge>::Get_CriticalPath(int ve[], int vl[]);
输入说明 :
第一行:图的类型
第二行:结点数
第三行:结点集
第四行:边数
第五行:边集
第六行:权集
输出说明 :
第一行:顶点集
第二行:邻接表
空行
顶点i Ve[i] Vl[i](列与列之间用格式控制符’\t’分隔)
…
空行
<弧尾,弧头> e[k] l[k](列与列之间用格式控制符’\t’分隔)
…
空行
<弧尾,弧头>-><弧尾,弧头>…
输入范例 :
DN
6
A B C D E F
8
0 1
0 2
1 3
1 4
2 3
2 5
3 5
4 5
3 2 2 3 4 3 2 1
输出范例 :
A B C D E F
A->2(2)->1(3)
B->4(3)->3(2)
C->5(3)->3(4)
D->5(2)
E->5(1)
F
A 0 0
B 3 4
C 2 2
D 6 6
E 6 7
F 8 8
<A,C> 0 0
<A,B> 0 1
<B,E> 3 4
<B,D> 3 4
<C,F> 2 5
<C,D> 2 2
<D,F> 6 6
<E,F> 6 7
(A,C)->(C,D)->(D,F)
数据结构-秋(一共34道题)
需要代做加qq1975728171
问题描述 :
目的:使用自行设计的顺序表ADT或STL中的vector模板,设计并实现顺序表应用场合的一些简单算法设计。
应用1:试设计一个算法,用尽可能少的辅助空间将非空顺序表中前 m 个元素和后 n 个元素进行互换,即将线性表(a1,a2,…,am,b1,b2,…,bn) 改变成(b1,b2,…,bn,a1,a2,…,am)。假定m始终是有效值。
参考函数原型:
(1)顺序表ADT版本
template
void Exchange( SqList &A, int m ); // 本算法实现顺序表中前 m 个元素和后 n 个元素的互换
(2)vector版本
template
void Exchange( vector &A, int m );// 本算法实现顺序表中前 m 个元素和后 n 个元素的互换
输入说明 :
第一行:顺序表的数据元素类型标记(0:int;1:double;2:char;3:string;其余值:输出err)
第二行:待处理顺序表的数据元素(数据元素之间以空格分隔)
第三行:逆置位置m
输出说明 :
第一行:逆置前顺序表的遍历结果(数据元素之间以“,”分隔)
空行
第三行:逆置后顺序表的遍历结果(数据元素之间以“,”分隔)
输入范例 :
0
13 5 27 9 32 123 76 98 54 87
5
输出范例 :
13,5,27,9,32,123,76,98,54,87
123,76,98,54,87,13,5,27,9,32
目的:使用C++模板设计并逐步完善图的邻接表抽象数据类型(ADT)。
内容:(1)请参照图的邻接矩阵模板类原型,设计并逐步完善图的邻接表ADT。(由于该环境目前仅支持单文件的编译,故将所有内容都集中在一个源文件内。在实际的设计中,推荐将抽象类及对应的派生类分别放在单独的头文件中。)
(2)设计并实现一个算法,基于广度优先搜索的思想,对于给定的有向图(网),实现拓扑排序。如排序成功,返回true;否则返回false。无论排序是否成功,都请给出最终的排序结果。图的存储结构采用邻接表。将其加入到ADT中。
注意:DG(有向图), DN(有向网), UDG(无向图), UDN(无向网)
提示:可以利用广度优先搜索(BFS)的思想来实现。和普通的广度优先搜索不同的是,一个结点只有当所有可以到达该结点的其它结点都已被访问后才可以被访问。BFS通常借助一个队列来实现,队列中存放的是可以被访问的结点。实现拓扑排序的过程如下:
(1)计算每个结点的入度,保存在数组inDegree中;
(2)检查inDegree中的每个元素,将入度为0的结点入队;
(3)不断从队列中将入度为0的结点出队,输出此结点,并将其对应的visit值赋为1,同时将该结点的入度不为0的后继结点的入度减1;如果某个邻接点的入度为0且未被访问过,则将其入队;
(4)重复步骤3,直到队列为空。如拓扑序列包含了图的全部结点,则排序成功,否则失败。
目的:使用C++模板设计并逐步完善图的邻接矩阵抽象数据类型(ADT)。
内容:(1)请参照图的邻接矩阵模板类原型,设计并逐步完善图的邻接矩阵ADT。(由于该环境目前仅支持单文件的编译,故将所有内容都集中在一个源文件内。在实际的设计中,推荐将抽象类及对应的派生类分别放在单独的头文件中。)
(2)设计并实现一个算法,使用队列,对一个已存在的图进行广度优先遍历(BFS),并输出遍历的顶点线性序列。遍历的起点通过输入指定。注意:遍历时,仅从该点出发遍历整个图,如果图不连通,则只遍历一个子图。图的存储结构采用邻接矩阵。将其加入到ADT中。
函数原型:
void BFS_Traverse(int u); //BFS遍历
辅助函数原型:
(1)int GetFirstAdjVex(int u, int &v); //返回G中指定顶点u的第一个邻接顶点的位序(顶点集)。若顶点在G中没有邻接顶点,则返回-1
(2)int GetNextAdjVex(int u, int v, int &w); //返回G中指定顶点u的下一个邻接顶点(相对于v)的位序(顶点集)。若顶点在G中没有邻接顶点,则返回-1
注意:DG(有向图), DN(有向网), UDG(无向图), UDN(无向网)
图的邻接矩阵模板类原型参考如下:
template <class TypeOfVer, class TypeOfEdge>
class adjmatrix_graph{
private:
int Vers; //顶点数
int Edges; //边数
TypeOfEdge **edge; //存放邻接矩阵(TypeOfEdge表示顶点关系类型。对于无权图,用1或0,表示相邻否;对于带权图,则为权值类型)
TypeOfVer *ver; //存放结点值
TypeOfEdge noEdge; //邻接矩阵中的∞的表示值
string GraphKind; //图的种类标志
bool DFS(int u, int &num, int visited[]); //DFS遍历(递归部分)
public:
adjmatrix_graph( const string &kd, int vSize, const TypeOfVer d[], const TypeOfEdge noEdgeFlag); //构造函数构造一个只有结点没有边的图。4个参数的含义:图的类型、结点数、结点值和邻接矩阵中表示结点间没有边的标记(无权图:0,有权图:输入参数定)
adjmatrix_graph( const string &kd, int vSize, int eSize, const TypeOfVer d[], int **e); //构造函数构造一个无权图。5个参数的含义:图的类型、结点数、边数、结点集和边集
adjmatrix_graph( const string &kd, int vSize, int eSize, const TypeOfEdge noEdgeFlag, const TypeOfVer d[], int **e, const TypeOfEdge w[]); //构造函数构造一个有权图。7个参数的含义:图的类型、结点数、边数、无边标记、结点集、边集、权集
bool GraphisEmpty() { return Vers == 0; } //判断图空否
string GetGraphKind(){ return GraphKind; }
bool GetVer(int u, TypeOfVer &data); //取得G中指定顶点的值
int GetFirstAdjVex(int u, int &v); //返回G中指定顶点u的第一个邻接顶点的位序(顶点集)。若顶点在G中没有邻接顶点,则返回-1
int GetNextAdjVex(int u, int v, int &w); //返回G中指定顶点u的下一个邻接顶点(相对于v)的位序(顶点集)。若顶点在G中没有邻接顶点,则返回-1
bool PutVer(int u, TypeOfVer data); //对G中指定顶点赋值
bool InsertVer(const TypeOfVer &data); //往G中添加一个顶点
int LocateVer(TypeOfVer data); //返回G中指定顶点的位置
bool PrintMatrix(); //输出邻接矩阵
int GetVerNum(){ return Vers;} //取得当前顶点数
int GetEdgeNum(){ return Edges;} //取得当前边数
bool Insert_Edge(int u, int v); //无权图插入一条边
bool Insert_Edge(int u, int v, TypeOfEdge w); //有权图插入一条边
bool DeleteVer(const TypeOfVer &data); //往G中删除一个顶点
bool Delete_Edge(int u, int v); //无权图删除一条边
bool Delete_Edge(int u, int v, TypeOfEdge w); //有权图删除一条边
void DFS_Traverse(int u); //DFS遍历(外壳部分)
void BFS_Traverse(int u); //BFS遍历
~adjmatrix_graph(); //析构函数
};
面向对象编程(一共27道题)
需要代做加qq1975728171
实验目的:学习拷贝构造函数、析构函数的使用以及重载等于号。
实验内容:
设计一个类Note(提醒),包含时间和事件内容,时间由年月日时分秒组成,事件内容用字符串表示。
类的编码大致如下:
class Note
{
int year, month, day, hour, minute, second;
char *event; //本题要求event必须为一个字符串指针,不能为字符数组或string字符串
//以下只说明了两个构造函数,可根据需要自己增加构造函数的重载
Note(char * msg, int year, int month, int day, int hour=0, int minute=0, int second=0);
Note(const Note & note);
~Note();
//还需要重载等于号,还可根据需要设计ShowNote()方法,用来显示“提醒”的时间和内容
}
再设计一个提醒列表类:NoteList,
私有数据成员包含一个Note数组(如果可能,最好使用vector代替数组)
还有以下成员函数:
插入提醒信息(插入后保持按时间升序排序,如果两个提醒信息时间完全相同,则后插入的排在后)
删除数组中第0个提醒信息并作为函数值返回(因为是按时间排序,所以第0个肯定是时间最早的一个)
输出所有提醒信息
获得提醒信息的数量
NoteList的成员大致为:
数据成员:
一个Note数组:noteArr
一个int成员:noteCount
函数成员:
构造函数
AddNote(Note n):插入提醒信息(插入后保持按时间升序排序)
Note DeleteFirst(): 删除数组中第0个提醒信息,并将其作为函数值返回
PrintAll():输出所有提醒信息
GetNoteCount():获得提醒信息的数量
可根据自己需要再增加其它成员。
main函数参考如下代码:
int main()
{
char eventMsg[100];
Note n2;
int year,month,day,hour,minute,second;
int i,n;
NoteList notes;
int op;
while (cin >> op)
{
switch (op)
{
case 1:
{
cin>>year;
cin>>month;
cin>>day;
cin>>hour;
cin>>minute;
cin>>second;
cin.get();
cin.getline(eventMsg,90);
Note nt(eventMsg,year,month,day,hour,minute,second);
notes.AddNote(nt);
break;
}
case 2:
{
if (notes.GetNoteCount()>0)
{
Note nt=notes.DeleteFirst();
nt.ShowNote();
}
break;
}
case 3:
{
int cnt = notes.GetNoteCount();
cout<<cnt<<" notes:"<<endl;
notes.PrintAll();
break;
}
}
}
return 0;
}
输入说明 :
可输入多组测试数据,每组测试数据包含一行或者两行:
第一行输入一个操作的种类:
1:输入一个提醒信息并插入
2:输出并删除提醒列表中时间最早的信息
3:输出所有提醒信息。
第二行输入所需要的参数:
对于第1个操作,第二行输入年月日时分秒及提醒信息字符串,以一个空格分隔各数据,提醒信息中可包含空格。
对于第2个操作和第3个操作,不需要输入额外数据。
输入中无多余空格或空行,两组测试数据之间也无空行。
输出说明 :
第1个操作无输出。
第2个操作输出一个提醒事件的具体信息,格式如下:
2020-01-01 08:10:10 go to class
其中,年月日之间以一个减号分隔,时分秒之间以一个冒号分隔,日期后及秒钟后跟一个空格,最后是提醒事件的内容(字符串),注意不要包含多余空格。
月日及时分秒的输出均占两位,如果不足两位,在前面补“0”。
第3个操作输出所有提醒事件的信息,格式如下:
2 notes:
2020-01-01 08:10:10 go to class
2020-01-01 10:00:00 go to library
第一行输出共有多少个notes,然后跟n行,
每个提醒信息占一行,输出格式见第2个操作的描述。
输出中无多余空格,也无多余空行。
输入范例 :
1
2010 1 1 9 0 0 go to class
1
2010 1 1 7 0 0 get up
1
2010 1 1 7 0 0 call zhang san
3
2
2
3
输出范例 :
3 notes:
2010-01-01 07:00:00 get up
2010-01-01 07:00:00 call zhang san
2010-01-01 09:00:00 go to class
2010-01-01 07:00:00 get up
2010-01-01 07:00:00 call zhang san
1 notes:
2010-01-01 09:00:00 go to class
实验目的:学习函数的默认形参的使用。
内容:对于字符串,实现以下填充函数,并编写main函数测试这些函数:
- padLeft函数:
功能:将一字符串左填充(在左边填充指定字符)至n个字符的长度,可指定填充字符,比如填充“*”,如果不指定填充字符,则填充空格。
提示:为实现以上功能,函数原型可为:
void padLeft(char string1[], char string2[], int n, char padding=’ ')
或:
string padLeft(string string1, int n, char padding=' ')
这里使用了默认形参。
string1是原字符串,string2是填充之后的结果。
类似地,可编写右填充函数,函数原型参照padLeft。
- padRight函数:
功能:将一字符串右填充至n个字符的长度,可指定填充字符,比如填充“*”,如果不指定填充字符,则填充空格。
main函数可参考如下进行编写:
int main()
{
int num, length;
char padding;
string src, dest;
while(cin >> num)
{
switch(num)
{
case 11:
cin >> src >> length;
cout << padLeft(src, length) << endl;
break;
case 12:
cin >> src >> length >> padding;
cout << padLeft(src, length, padding) << endl;
break;
case 21:
cin >> src >> length;
cout << padRight(src, length) << endl;
break;
case 22:
cin >> src >> length >> padding;
cout << padRight(src, length, padding) << endl;
break;
}
}
return 0;
}
输入说明 :
测试程序输入时,每组测试数据包含两行,第一行输入一个整数,指定需要完成的操作,第二行为该操作需要的数据。
对于每个整数对应的操作及其相应数据的输入方式如下(输入的字符串中不包含空格):
11:对应padLeft,第二行输入字符串string1、整数n,其间以空格分隔(由于没指定填充字符,所以填充空格)
异常处理:如果string1的长度大于等于n,则不填充任何字符。
12:对应padLeft,第二行输入字符串string1、整数n、一个填充字符,其间以空格分隔(填充字符不为空格)
异常处理:如果string1的长度大于等于n,则不填充任何字符。
21:对应padRight,第二行输入字符串string1、整数n,其间以空格分隔(由于没指定填充字符,所以填充空格)
异常处理:如果string1的长度大于等于n,则不填充任何字符。
22:对应padRight,第二行输入字符串string1、整数n、一个填充字符,其间以空格分隔(填充字符不为空格)
异常处理:如果string1的长度大于等于n,则不填充任何字符。
输出说明 :
对于每组测试数据,输出对应的结果。如果结果为空字符串,则输出一个空行。
每行行首与行尾无多余空格,第一行之前与最后一行之后无多余空行。
输入范例 :
11
abcdef 4
12
abcdef 8 *
21
abcdef 6
22
abcdef 10 .
输出范例 :
abcdef
**abcdef
abcdef
abcdef…
实验目的:多态的应用
实验内容:
公司有三类雇员:老板、销售员、实习生。
老板每月固定5000元;销售员每月2000元底薪加提成,提成的计算方式为销售额的10%;实习生的工资按实习时间计算,每小时30元。
现输入若干雇员的信息,请输出一个月该发多少工资。
要求:
首先声明类employee,包含:
数据成员:
string name;
string role;
double salary;
以及
构造函数:employee(string name, string role),并且仅声明这一个构造函数,无默认构造函数。
虚函数calcSalary
普通成员函数showInformation(该输出雇员的姓名、角色、工资信息)
普通成员函数getSalary(返回salary的值)
再声明三个employee的派生类:boss、salesman、intern,类中需要实现虚函数calcSalary。
在main函数中,首先输入若干雇员的信息,放入empList中,然后遍历empList,计算各雇员的工资,输出其信息,最后输出总工资。
问题描述:试定义一个实现计算学生课程成绩的类Student,对学生学期总评成绩进行计算并排序。具体要求如下:
(1)私有数据成员:
int norm, ex, final,overall:分别表示学生的平时成绩、实验成绩、期末考试和总评成绩
char name[15]:学生姓名
(2)公有成员函数:
void init(char *name1, int nor1, int ex1, int fin1); 用参数name1,nor1,exp1,fin1分别初始化数据成员name,norm, ex, final
void fun( ); 计算学生的总评成绩。
计算方法为:总评成绩=平时成绩占20%+实验成绩占25%+期末成绩占*55%。总评成绩计算时要求四舍五入,并且期末考试成绩不足50分时,则期末考试成绩即为总评成绩。
void print( ); 输出该学生信息。
(3)友元函数:
friend void sort(Student st[], int n); 友元函数,对st按总评成绩进行从大到小排序