北邮数据结构实验四题目1
北邮算法与数据结构4

数据结构---第四章 串 11
S2
Status SubString(HString &Sub, HString S, int pos, int len) //求串S从第pos个字符起长度为len的子串Sub { if ( (pos<1 || pos >S.length || len<0 || len > S.length-pos+1 ) return ERROR; if (Sub.ch) free(Sub.ch); if ( !len ) { Sub.ch=NULL; Sub.length=0; } else { if ( !(Sub.ch=(char *)malloc(len* sizeof(char)))) exit(OVERFLOW); Sub.ch[0..len-1]=S.ch[pos-1..pos+len-2]; Sub.length=len; } pos-1 0 S.length-1 return OK; } // SubString len
数据结构---第四章 串 2
4.1.2 串的常用基本操作 (1)用串常量赋值 用串变量赋值 (2)判定空串 (3)两串比较 (4)求串长 (5)串清空 (6)两串连接 (7)求子串 (8)子串定位 (9)子串置换 (10)插入子串 (11)删除子串 (12)串销毁 StrAssign(&T, chars) StrCopy(&T, S) StrEmpty(S) StrCompare(S, T) StrLength(S) ClearString(&S) Concat(&T, S1, S2) SubString(&Sub, S, pos, len) Index(S, T, pos) Replace(&S, T, V) StrInsert(&S, pos, T) StrDelete(&S, pos, len) DestroyString(&S)
数据结构实验考试题

第 1 题:报数问题(时间限制为:5000毫秒)5输入:标准输入输出:标准输出描述:n个人围成一个圈,每个人分别标注为1、2、...、n,要求从1号从1开始报数,报到k的人出圈,接着下一个人又从1开始报数,如此循环,直到只剩最后一个人时,该人即为胜利者。
例如当n=10,k=4时,依次出列的人分别为4、8、2、7、3、10,9、1、6、5,则5号位置的人为胜利者。
给定n个人,请你编程计算出最后胜利者标号数。
输入:输入包含若干个用例,每个用例为接受键盘输入的两个数n(1<=n<=1000000), k(1<=k<=50),分别表示总人数及报到出圈数。
输入为“0 0“表示输入用例结束。
输出:每个用例用一行输出最后胜利者的标号数。
输入样例1:1 110 40 0输出样例1:15第2题:成绩统计(顺序线性表)(时间限制为:1000毫秒)描述:根据输入统计学生的平均分及各科平均分。
输入:第一行为学生的个数n及课程数m,第二行至m+1行为课程名,接下来为各学生的姓名及成绩,每个学生的信息占两行,第一行为学生的姓名,第二行为m个实数,表示学生各科成绩。
输出:输出包含2n+2m行,前2n行为学生的平均分,其中第一行为学生姓名,第二行为该生的平均分,后2m行为各课程的平均分,其中第一行为课程名,第二行为对应的平均分。
(保留两位小数)样例输入:3 2englishcomputerzhangshan87.5 98lisi80 78wangwu60 59样例输出:zhangshan92.75lisi79.00wangwu59.50english75.83computer78.33第3题:合并线性表(时间限制为:500毫秒)描述:已知两非递减的顺序线性表,要求合并成一个新的非递减顺序线性表。
输入:输入包含四行,第一行为自然数n,表示第一个非递减顺序线性表的长度,第二行为n个自然数构成的非递减顺序线性表,第三行为自然数m,表示第二个非递减顺序线性表的长度,第四行为m个自然数构成的非递减顺序线性表。
北邮数据结构实验报告

北邮数据结构实验报告摘要:本报告基于北邮数据结构实验,通过实际操作和实验结果的分析,总结和讨论了各实验的目的、实验过程、实验结果以及相关的问题和解决方法。
本报告旨在帮助读者了解数据结构实验的基本原理和应用,并为今后的学习和研究提供参考。
1. 实验一:线性表的操作1.1 实验目的本实验旨在掌握线性表的基本操作以及对应的算法实现,包括插入、删除、查找、修改等。
1.2 实验过程我们使用C++语言编写了线性表的相关算法,并在实际编程环境下进行了测试。
通过插入元素、删除元素、查找元素和修改元素的操作,验证了算法的正确性和效率。
1.3 实验结果经过测试,我们发现线性表的插入和删除操作的时间复杂度为O(n),查找操作的时间复杂度为O(n),修改操作的时间复杂度为O(1)。
这些结果与预期相符,并反映了线性表的基本特性。
1.4 问题与解决方法在实验过程中,我们遇到了一些问题,例如插入操作的边界条件判断、删除操作时的内存释放等。
通过仔细分析问题,我们优化了算法的实现,并解决了这些问题。
2. 实验二:栈和队列的应用2.1 实验目的本实验旨在掌握栈和队列的基本原理、操作和应用,并进行实际编程实现。
2.2 实验过程我们使用C++语言编写了栈和队列的相关算法,并在实际编程环境下进行了测试。
通过栈的应用实现表达式求值和逆波兰表达式的计算,以及队列的应用实现图的广度优先遍历,验证了算法的正确性和效率。
2.3 实验结果经过测试,我们发现栈的应用可以实现表达式的求值和逆波兰表达式的计算,队列的应用可以实现图的广度优先遍历。
这些结果证明了栈和队列在实际应用中的重要性和有效性。
2.4 问题与解决方法在实验过程中,我们遇到了一些问题,例如中缀表达式转后缀表达式的算法设计、表达式求值的优化等。
通过查阅资料和与同学的讨论,我们解决了这些问题,并完善了算法的实现。
3. 实验三:串的模式匹配3.1 实验目的本实验旨在掌握串的基本操作和模式匹配算法,并进行实际编程实现。
北邮数据结构实验四-链表排序

数据结构实验报告实验名称:实验四——链表的排序学生姓名:班级:班内序号:学号:日期:1.实验要求[内容要求]使用链表实现下面各种排序算法,并进行比较。
排序算法:1、插入排序2、冒泡排序3、快速排序4、简单选择排序5、其他要求:1、测试数据分成三类:正序、逆序、随机数据2、对于这三类数据,比较上述排序算法中关键字的比较次数和移动次数(其中关键字交换计为3次移动)。
3、对于这三类数据,比较上述排序算法中不同算法的执行时间,精确到微秒(选作)4、对2和3的结果进行分析,验证上述各种算法的时间复杂度编写测试main()函数测试线性表的正确性代码要求1、必须要有异常处理,比如删除空链表时需要抛出异常;2、保持良好的编程的风格:代码段与段之间要有空行和缩近标识符名称应该与其代表的意义一致函数名之前应该添加注释说明该函数的功能关键代码应说明其功能3、递归程序注意调用的过程,防止栈溢出2. 程序分析2.1 存储结构[内容要求]存储结构:双链表2.2 关键算法分析[内容要求]定义类:template <class T>class LinkList{public:LinkList(){front = new Node <T>;front->next=rear;front->prior=NULL;rear=newNode<T>;rear->next=NULL;rear->prior=front;}LinkList(T a[],int n);void BackLinkList(T a[]);//恢复原链表~LinkList();//析构函数void PrintList();//打印数列void InsertSort();//插入排序void BubbleSort();//冒泡排序Node <T>* Partion(Node <T> *i,Node <T> *j);//快速排序中寻找轴值的函数void Qsort(Node <T> *i,Node <T> *j);//快速排序void SelectSort();//选择排序Node<T>*front;Node<T>*rear;};成员函数包括:构造函数:单链表,打印单链表,插入排序,快速排序,冒泡排序,选择排序,析构函数公有成员:头指针和尾指针1、构造函数:LinkList<T>::LinkList(T a[],int n){front=new Node<T>;rear=new Node<T>;front->prior=NULL;front->next=rear;rear->next=NULL;rear->prior=front;Node <T>*s;for (int i=n-1;i>=0;i--){s=new Node<T>;s->data=a[i];s->next=front->next;front->next=s;s->prior=front;s->next->prior=s;}}2、析构函数LinkList<T>::~LinkList(){Node<T> *p=front->next;while(p->next!=NULL){delete p->prior;p=p->next;}delete rear;front=NULL;rear=NULL;}3、打印函数template <class T>void LinkList<T>::PrintList(){Node<T> *p=front->next;while(p->next!=NULL){cout<<p->data<<" ";p=p->next;}cout<<endl;}4、插入排序template <class T>void LinkList<T>::InsertSort(){Node<T> *p=front->next->next;Node<T> *q;T temp;while (p->next!=NULL){if (p->data<p->prior->data){temp=p->data;MoveCount++;q=p->prior;while (temp<q->data){q->next->data=q->data;q=q->prior;CompareCount++;MoveCount++;}q->next->data=temp;MoveCount++;}CompareCount++;p=p->next;}}将链表分为有序区和无序区,分别将无序区的每一个元素插入到有序区的相应位置。
(完整word)北邮C++数据结构课后习题 习题4参考答案

习题41.填空题(1)已知二叉树中叶子数为50,仅有一个孩子的结点数为30,则总结点数为(___________)。
答案:129(2)4个结点可构成(___________)棵不同形态的二叉树。
答案:12(3)设树的度为5,其中度为1~5的结点数分别为6、5、4、3、2个,则该树共有(___________)个叶子。
答案:31(4)在结点个数为n(n〉1)的各棵普通树中,高度最小的树的高度是(___________),它有(___________)个叶子结点,(___________)个分支结点。
高度最大的树的高度是(___________),它有(___________)个叶子结点,(___________)个分支结点。
答案:2 n—1 1 n 1 n-1(5)深度为k的二叉树,至多有(___________)个结点。
答案:2k-1(6)有n个结点并且其高度为n的二叉树的数目是(___________)。
答案:2n—1(7)设只包含根结点的二叉树的高度为1,则高度为k的二叉树的最大结点数为(___________),最小结点数为(___________)。
答案:2k-1 k(8)将一棵有100个结点的完全二叉树按层编号,则编号为49的结点为X,其双亲PARENT(X)的编号为().答案:24(9)已知一棵完全二叉树中共有768个结点,则该树中共有(___________)个叶子结点。
答案:384(10)已知一棵完全二叉树的第8层有8个结点,则其叶子结点数是(___________).答案:68(11)深度为8(根的层次号为1)的满二叉树有(___________)个叶子结点。
答案:128(12)一棵二叉树的前序遍历是FCABED,中序遍历是ACBFED,则后序遍历是(___________).答案:ABCDEF(13)某二叉树结点的中序遍历序列为ABCDEFG,后序遍历序列为BDCAFGE,则该二叉树结点的前序遍历序列为(___________),该二叉树对应的树林包括(___________)棵树。
北邮数据结构实验报告实验四

2009级数据结构实验报告实验名称:实验四——排序学生姓名:班级:班内序号:学号:日期:2010/12/171.实验要求实验目的:通过选择下面两个题目之一,学习、实现、对比各种排序算法,掌握各种排序算法的优劣,以及各种算法使用的情况。
实验内容:使用简单数组实现下面各种排序算法,并进行比较。
排序算法:1、插入排序2、希尔排序3、冒泡排序4、快速排序5、简单选择排序6、堆排序7、归并排序8、基数排序(选作)9、其他要求:1、测试数据分成三类:正序、逆序、随机数据2、对于这三类数据,比较上述排序算法中关键字的比较次数和移动次数(其中关键字交换计为3次移动)。
3、对于这三类数据,比较上述排序算法中不同算法的执行时间,精确到微秒(选作)4、对2和3的结果进行分析,验证上述各种算法的时间复杂度编写测试main()函数测试线性表的正确性。
2. 程序分析2.1 存储结构使用最简单的一维数组存储待排序的数据。
共使用两个数组,一个用来存储原始数据,一个用来存储待排序数据。
每次排序完毕,用原始数据更新一次待排序数据,保证每一次都对同一组数据排序。
(图略)2.2 关键算法分析1.直接插入的改进:在一般的直接插入中,关键码每移动一次就需要比较一次。
在移动的方面,优化是比较困难的,因为对静态线性表的插入必然要带来大量的移动。
但是,我们可以在比较上进行一些优化。
在查找技术一张曾学过的“折半查找法”,在这里就可以照葫芦画瓢地运用。
一趟排序的伪代码如下:1.如果该元素大于处于其左侧相邻的元素则跳过该元素;2.low=0,high=i;3.循环直至low==high3.1 mid=(low+high)/2;3.2如果当前元素大于中值high=mid;3.3否则low=mid+1;4.当前元素赋值给临时变量;5.将有序区中处于low位置及其右侧的元素右移;6.临时变量置于low位置简单说一下这里的折半查找与一般查找算法的区别。
这里的查找,尤其是对无重复数据和大量数据的处理中,更多的时候是找不到完全相等的项的。
北邮C++实验四作业

5.3 实验题一、基础题1.修改下列程序中的错误,输出结果,输出示例如图5-1所示。
并对有注释标记的语句进行功能注释。
#include<iostream>usingnamespace std;void f1(int x[ ]){for(int i=0;i<10;i++){x[i]=2*x[i]+1;if(i==5) //第六个元素后换行cout<<x[i]<<endl;elsecout<<x[i]<<" ";}cout<<endl;}void main(){int a[10];for(int i=0;i<10;i++)cin>>a[i]; //输入并赋值给数组a[]f1(a); //执行函数f1()system("pause");}2.修改下列程序的错误,完成求最大数的功能。
#include<iostream>usingnamespace std;inlineint f1(int x,int y){return x>y?x:y;}void main(){ int a=120,b=300,c=40;int d,e,f;d=f1(a,b);e=f1(d,c);cout<<"a="<<a<<endl;cout<<"b="<<b<<endl;cout<<"c="<<c<<endl;cout<<"三¨y个?数ºy中D的Ì?最Á?大䨮数ºy为a:"<<e<<endl; system("pause");}3.分析程序出错的原因,并更正、输出正确的结果。
北邮数据结构实验四链表排序

数据结构实验报告实验名称:学生姓名:班级:班内序号:学号:日期:实验描述:使用链表实现下面各种排序算法,并进行比较。
排序算法:1、插入排序2、冒泡排序3、快速排序4、简单选择排序5、其他一.程序分析1.存储结构:双向链表2.关键算法分析:a)插入排序:⒈从有序数列和无序数列{a2,a3,…,an}开始进行排序;⒉处理第i个元素时(i=2,3,…,n),数列{a1,a2,…,ai-1}是已有序的,而数列{ai,ai+1,…,an}是无序的。
用ai与ai-1,a i-2,…,a1进行比较,找出合适的位置将ai插入;⒊重复第二步,共进行n-i次插入处理,数列全部有序。
b)冒泡排序:1.比较相邻的元素。
如果第一个比第二个大,就交换他们两个。
2.对每一对相邻元素作同样的工作,从开始第一对到结尾的最后一对。
在这一点,最后的元素应该会是最大的数。
3.针对所有的元素重复以上的步骤,除了最后一个。
4.持续每次对越来越少的元素重复上面的步骤,直到没有任何一对数字需要比较。
c)快速排序:一趟快速排序的算法是:1.设置两个变量i、j,排序开始的时候:i=0,j=N-1;2.以第一个数组元素作为关键数据,赋值给key,即key=A[0];3.从j开始向前搜索,即由后开始向前搜索(j--),找到第一个小于key的值A[j],将A[j]和A[i]互换;4.从i开始向后搜索,即由前开始向后搜索(i++),找到第一个大于key的A[i],将A[i]和A[j]互换;5.重复第3、4步,直到i=j;(3,4步中,没找到符合条件的值,即3中A[j]不小于key,4中A[i]不大于key的时候改变j、i的值,使得j=j-1,i=i+1,直至找到为止。
找到符合条件的值,进行交换的时候i,j指针位置不变。
另外,i==j这一过程一定正好是i+或j-完成的时候,此时令循环结束)。
d)简单选择排序:设所排序序列的记录个数为n。
i取1,2,…,n-1,从所有n-i+1个记录(Ri,Ri+1,…,Rn)中找出排序码最小的记录,与第i个记录交换。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
北邮数据结构实验报告实验名称:实验四排序学生姓名:XXX班级:XXX班内序号:XX学号:XXX日期:2013年12月20日1.实验要求a. 实验目的通过实现下述实验内容,学习、实现、对比各种排序算法,掌握各种排序算法的优劣,以及各种算法使用的情况。
b. 实验内容使用简单数组实现下面各种排序算法,并进行比较。
排序算法:1、插入排序2、希尔排序3、冒泡排序4、快速排序5、简单选择排序6、堆排序7、归并排序8、基数排序(选作)9、其他2. 程序分析2.1 存储结构存储结构:顺序存储结构示意图如下:2.2 关键算法分析核心算法思想:1.利用教材讲述的基本算法思想,实现七种排序算法,统计其运行相关数据。
2.将数组名当做地址传入函数,实现快速调用和统计。
使得程序代码可读性增、结构更加优化。
关键算法思想描述和实现:关键算法1:实现七种算法的基本排序功能。
1、插入排序:依次将待排序的序列中的每一个记录插入到先前排序好的序列中,直到全部记录排序完毕。
2、希尔排序:先将整个序列分割成若干个子列,分别在各个子列中运用直接插入排序,待整个序列基本有序时,再对全体记录进行一次直接插入排序。
3、冒泡排序:两两比较相邻记录的关键码,如果反序则交换,直到没有反序记录为止。
4、快速排序:首先选择一个基准,将记录分割为两部分,左支小于或等于基准,右支则大于基准,然后对两部分重复上述过程,直至整个序列排序完成。
5、选择排序:从待排序的记录序列中选择关键码最小(或最大)的记录并将它与序列中的第一个记录交换位置;然后从不包括第一个位置上的记录序列中选择关键码最小(或最大)的记录并将它与序列中的第二个记录交换位置;如此重复,直到序列中只剩下一个记录为止。
6、堆排序:通过建立大根堆或者小根堆,取出根节点,反复调整堆使之保持大根堆或者小根堆,直至最后序列有序。
7、归并排序:将若干个有序序列两两归并,直至所有待排序的记录都在一个有序序列为止。
C++实现:void Insert(int r[],int n) //直接插入排序,升序{int compare=0,move=0; 定义比较和移动的系数并初始化为零,以下相同不再叙述 for(int i=2;i<n;i++) 将数组中的数一个一个放入序列{if(r[i]<r[i-1]) 第一个位置当做哨兵,从第二个开始,若后面的数不比前面的数大则将哨兵入列,较小的数作为新哨兵{r[0]=r[i];int j;for (j=i-1;r[0]<r[j];j--) 若后面的数比哨兵大,则直接放进数列{r[j+1]=r[j];move++; 每进行一次上移动从操作则移动加1}r[j+1]=r[0];}compare++; 每判断一次比较加1}cout<<"比较次数:"<<compare<<" 移动次数:"<<move<<endl;}void ShellInsert(int r[],int n) //希尔排序{int compare=0,move=0;for(int d=n/2;d>=1;d=d/2) 主要思想每次循环跨越的步子折半{for(int i=d+1;i<n;i++) 依次比较每一个下标等差增长的数列{if(r[i]<r[i-d]) 判断,小的值放前面{r[0]=r[i];int j;for(j=i-d;j>0&&r[0]<r[j];j=j-d) 比较没一个数列内的元素r[j+d]=r[j];r[j+d]=r[0];move++;}compare++;}}cout<<"比较次数:"<<compare<<" 移动次数:"<<move<<endl;}void BubbleSort(int r[],int n) //改进后的冒泡排序{int compare=0,move=0;int pos=n;while(pos!=0) 判断循环的结束条件,下面会有介绍{int bound=pos;pos=0; 令pos初始化为0,之后如果没有进入循环修改其值则跳出while循环for(int i=1;i<bound-1;i++) bound为每次循环需要进行的次数,因为排好序的元素不需要再进行比较if(r[i]>r[i+1]) 大数后置{r[0]=r[i];r[i]=r[i+1];r[i+1]=r[0];pos=i+1;move++;}compare++;}}cout<<"比较次数:"<<compare<<" 移动次数:"<<move<<endl;}int Partion(int r[], int first, int end,int a,int b) //一次快排{int i=first; 头int j=end; 尾int pivot=r[i]; 哨兵while(i<j) 头在尾之前,即尚未遍历数组{while((i<j)&&(r[j]>=pivot)) 右侧扫瞄,大于哨兵的不动j--;a++;}r[i]=r[j]; 小小于哨兵的进入哨兵b++;while((i<j)&&(r[i]<=pivot)) 进行左侧扫描,小于哨兵的写入数组{i++;a++;}r[j]=r[i]; 否则,进入哨兵b++;}r[i]=pivot; 哨兵入列return i;}void Qsort(int r[],int i,int j) //运用递归实现多次快排{if(i<j){int pivotloc=Partion(r,i,j,a,b); 依次分割排序区间Qsort(r,i,pivotloc-1);Qsort(r,pivotloc+1,j);}}void SelectSort(int r[],int n) //简单选择排序{int compare=0,move=0;for(int i=1;i<n;i++) 目前比较开始的元素{int min=i; 为了判断目前的元素是否为最小for(int j=i+1;j<n;j++) 那当前元素和之后的元素比较{if(r[j]<r[min]) 找出最小当前最小的元素并贴上标记min=j;compare++;}if(min!=i) 如果标记被改变,就交换标记改变前后位置的元素,否则标记的元素即为最小不用改变{r[0]=r[i];r[i]=r[min];r[min]=r[0];move++;}}cout<<"比较次数:"<<compare<<" 移动次数:"<<move<<endl;}void Sift(int r[],int k,int m) //小根堆的筛选{int i=k,j=2*i;while(j<=m) 循环结束的条件,最后的子节点大于总结点{if(j<m&&r[j]>r[j+1]) 比较左右孩子的大小,并将j指向较小的孩子j++;if(r[i]<r[j]) 父节点比最大的子节点小则该堆建成,跳出循环break;else 否则把父节点往下筛{r[0]=r[j];r[j]=r[i];r[i]=r[0];i=j;j=2*i;}}}void HeapSort(int r[],int n) //小根堆排序{for(int i=n/2;i>=1;i--) 从最后一个有字节点的节点开始建小根堆Sift(r,i,n);for(int i=1;i<n;i++) 依次取出每一个小跟对的根节点,再重新筛,形成有序数列{r[0]=r[n-i+1];r[n-i+1]=r[1];r[1]=r[0];Sift(r,1,n-i);}void Merge(int r[],int r1[],int s,int m,int t,int *c,int *d) r为要排序的数组,r1为缓冲数组,s为第一个序列开始的位置,m为第一个序列的结束的位置,t为第二个序列的结束位置,c为比较次数的指针,d为移动次数的指针{int i=s; 定义两个要归并的序列的起始位置int j=m+1;int k=s;while(i<=m&&j<=t) 循环条件,两个序列都不空{if(r[i]<r[j]) 将小数写进缓冲数组,小数对应的序列比较值后一一位{r1[k++]=r[i++];(*d)++;}else{r1[k++]=r[j++];(*d)++;}(*c)++;}if(i<=m) 当一个序列穷尽时,将另一个序列抄进缓冲数组while(i<=m){r1[k++]=r[i++];(*d)++;}if(j<=t)while(j<=t){r1[k++]=r[j++];(*d)++;}}void MergePass(int r[],int r1[],int n,int h,int *c,int *d) 将一个数组一次拆分成长度不同的小数组再两两归并{int i=1;while(i<=n-2*h+1) h为本次小序列的长度,当能拆成两个等长的序列时,拆出该序列进行归并{Merge(r,r1,i,i+h-1,i+2*h-1, c, d);i+=2*h; 每次归并完,序列长度增加一倍,再次归并}if(i<n-h+1) 当只能拆出一个单位长度的序列和一个残缺序列时,只将第二个序列归并到最大长度nMerge(r,r1,i,i+h-1,n,c,d);Else 只能拆出一个残序列时,只把该序列抄进缓冲数组即可for(;i<=n;i++){r1[i]=r[i];(*d)++;}}void MergeSort(int r[],int r1[],int n){int compare=0,move=0;int h=1; 起始拆分的序列长度定义为一,即每个数都需要进行比较 while(h<n) 依次展长序列长度进行归并{MergePass(r,r1,n,h,&compare,&move);h=2*h;for(int i=1;i<=n;i++) 将缓冲数组里的有序数写进原数组{r[i]=r1[i];move++;}}cout<<"比较次数:"<<compare<<" 移动次数:"<<move<<endl;}关键算法2:获取当前系统时间,精确到微秒,分别在代码运行前后调用记录前后时间,再相减即可得到代码运行时间。