一.你能结合自己的编程实践,谈一下数据结构和算法之间的关系吗?

**数据结构:**指的是数据元素之间的抽象的相互关系,并不涉及数据元素的具体内容。这种结构关系将数据组织成为某种形式的信息表,以便程序进行加工。而这信息的表示和组织形式又将直接影响加工程序的效率。

**算法:**是对特定问题求解步骤的一种描述,是指令的有限序列。

二.简单排序算法

1、 编程实现(直接) 冒泡排序算法、(直接)选择排序算法和(直接)插入排 序算法,分析其时间和空间复杂度。

**编程实现排序算法思路:**建立一个排序类,成员属性为一个容量为一百的数组(为了统一变量,也可以根据用户输入值,自动创建不同容量大小的随机数组,需要在堆区开辟数组,并重构析构函数手动释放)

class sort
{
public://无参构造函数,建立一个容量为100的随机数数组sort(){ srand((int)time(0));  // 产生随机种子  把0换成NULL也行for (int i = 0; i < 100; i++){  Arr[i] = rand() % 100;}}//打印函数,输出随机数数组void sortprint(){if (this == NULL) {return;}for (int i = 0; i < 100; i++){cout << Arr[i] << " ";}cout << endl;}//冒泡排序函数void BubbleSort(); //选择排序函数void SelectSort();//插入排序函数void InsertSort();//交换函数void swap(int &a, int &b){if (this == NULL) {return;}int temp = a;a = b;b = temp;}public:int Arr[100];
};

**冒泡排序算法基本思想:**把关键字较小的记录看成是“较轻的”,所以应当往上浮起。从后往前(或者从前往后)两两比较相邻元素的值,若为逆序则交换他们,直到比较完成,称之为第一趟冒泡。下一趟冒泡时,已经确定的最小元素将不再参与比较,每趟冒泡都会将当前序列的最小元素(或者最大元素)放到序列的最终位置,最多n-1躺冒泡,就能使序列元素有序。

时间复杂度:最好情况下,初始序列有序,只需经过第一趟冒泡排序,便结束循环,共比较了n-1次,此时的时间复杂度为O(n)。最坏情况下,初始序列为逆序,共需经过n-1趟排序,第i次排序需要进行n-i次比较,此时的时间复杂度为O(n2)。平均情况下,算法的时间复杂度也为O(n2)。

空间复杂度:算法实现只使用了有限个辅助单元,故空间复杂度为O(1)。

 void BubbleSort(){if (this == NULL) {return;}int i, j;for (i = 0; i <= 98; i++){bool flag = false;for (j = 99; j >= i + 1; j--)if (Arr[j] < Arr[j - 1]){swap(Arr[j], Arr[j - 1]);flag = true;}if (flag == false)return;}}

**选择排序算法基本思想:**每一趟在n-i+1(i=1,2,…n-1)个记录中选取关键字最小的记录作为有序序列中第i个记录。

时间复杂度:在该算法中,元素比较次数与序列初始情况无关,平均时间复杂度为O(n2)。

空间复杂度:该算法仅使用了有限个辅助单元,空间复杂度为O(1)。

 void SelectSort(){for (int i = 0; i < 99; i++) {int min = i;for (int j = i + 1; j < 100; j++)if (Arr[j] < Arr[min])min = j;if (min != i)swap(Arr[i], Arr[min]);}}

**插入排序算法基本思想:**每次将一个待排序的记录按其关键字大小插入前面已经排好的子序列中,直到全部记录插入完成。

**时间复杂度:**最好情况下,初始序列有序,此时每插入一个元素只需要比较一次,时间复杂度为O(n)。最坏情况下,初始序列为逆序,时间复杂度为O(n2)。平均情况下,算法的时间复杂度为O(n2)。

**空间复杂度:**算法仅使用了有限个辅助单元,空间复杂度为O(1)。

 void InsertSort(){if (this == NULL) {return;}int i, j, r;for(i=1;i<=99;i++)if (Arr[i] < Arr[i - 1]) {r = Arr[i];   //r相当于一个哨兵for (j = i - 1; r < Arr[j]; --j)Arr[j + 1] = Arr[j];Arr[j + 1] = r;}}

三种算法实验结果:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-iUVJmTPh-1677331824026)(.\assets\9I3FQ46]58IPZZ9%@`EA3V3.png)]

2、 编程实现(直接) 冒泡排序、(直接)选择排序和(直接)插入排序的递归算法,分析其时间和空间复杂度。

实验选用的数组是容量为20的随机生成数组

void SortBuild(int* Arr)
{srand((int)time(0));  // 产生随机种子  把0换成NULL也行for (int i = 0; i < 20; i++){Arr[i] = rand() % 100;}
}

递归实现冒泡排序算法:

时间复杂度:平均情况下,在第i躺排序时,得进行n-i次比较,时间复杂度为O(n2)。

空间复杂度:使用了有限个辅助单元,空间复杂度为O(1)。

//冒泡排序函数
void BubbleSort(int i, int j,int Arr[])
{if (i > 18)return;else if (j < i + 1)i++, j = 19;if (Arr[j] < Arr[j - 1])swap(Arr[j], Arr[j - 1]);BubbleSort(i, j - 1, Arr);}

递归实现选择排序算法:

时间复杂度:在该算法中,元素比较次数与序列初始情况无关,平均时间复杂度为O(n2)。

空间复杂度:每次递归调用,都会创建一个临时变量min用于存储待排序数组的最小值,空间复杂度为O(n)。在代码块中,将min变量放入else语句中,在进行下一次递归前该变量会被释放,应该能将空间复杂度优化至O(1)。

//选择排序函数
void SelectSort(int i, int j, int Arr[])
{int min = i;if (i >= 19)return;else {for (int j = i + 1; j < 20; j++) if (Arr[j] < Arr[min])min = j;if (min != i)swap(Arr[i], Arr[min]);}SelectSort(i + 1, j , Arr);
}

递归实现插入排序算法:

时间复杂度:从递归层数最深往最浅看,在倒数第i躺排序时,算法需要比较1到i次,平均时间复杂度为O(n2)

空间复杂度:每次递归都会创建临时变量r,i,空间复杂度为O(n)。

void InsertSort(int len, int Arr[])
{int r, i;//r用于保存当前的最后一个元素if (len > 1){InsertSort(len - 1, Arr);r = Arr[len - 1];for (i = len - 2; i >= 0 && Arr[i] > r; i--)Arr[i + 1] = Arr[i];//元素后移Arr[i + 1] = r;//插入正确的位置}elsereturn;
}

三种算法实验结果:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-cDZKViJl-1677331824027)(./assets/4LI2AS34_[5U9X]{Q5TRRV7.png)]

3、 你能用实验的方法验证上述算法时间复杂度的分析结论吗?

三.汉诺塔问题

1、 编程实现汉诺塔问题的递归算法,并分析的时间和空间复杂度。

有A、B、C三根柱子,现在A柱子上面从下往上按照大小顺序放着n片圆盘,规定任何时候小圆盘上面都不能放着大圆盘,且三根柱子之间一次只能移动一个圆盘。请问把A柱子上的圆盘移动到C柱子上面,需要移动多少次?

  1. 先通过递归将A的前n-1个盘子移动到B
  2. 再把A第n个盘子移动到C
  3. 最后将B上的n-1个盘子移动到C

时间复杂度:观察上面的步骤可以发现,T(n)=2T(n-1)+1,算法的时间复杂度为O(2n)。

空间复杂度:算法无需太多辅助单元,空间复杂度为O(1)。

void HannoiTower(int n, char a , char b , char c )
//第二个参数为起始柱,第三个参数为中间柱,第四个参数为目标柱
{if (n == 0){return ; }HannoiTower(n - 1, a, c, b);//先通过递归将A的前n-1个盘子移动到Bi++;//计数 cout << a << "移动至" << c << endl; //再把A第n个盘子移动到CHannoiTower(n - 1, b, a, c);//最后将B上的n-1个盘子移动到C }

实验截图:

2、 你能将汉诺塔的递归算法改写成非递归算法吗?并分析其时间和空间复 杂度。

所有的汉诺塔问题,都可以通过重复的两步来解决,同样假设现在A柱上面有n个圆盘,三根柱子的顺序为A-B-C。

  1. 将三根柱子上最小的圆盘移动到下一根柱子上面
  2. 除了最小盘移动到的柱子外,判断剩下的两根柱子上面的盘子大小,将较小的圆盘移动到较大的圆盘上面。如果有空杆则移动到空杆上面。

如此重复上述两个步骤,当n为奇数时,最终所有圆盘会放到B柱上;当n为偶数时,最终所有圆盘会放到C柱上。

思路:给A设立一个数组,初始化为1到n,代表盘子从小到大。再给B和C初始化一个相同大小的数组,全为0,代表为空。

void HannoiTower(int n, char a, char b, char c)
//第二个参数为起始柱,第三个参数为中间柱,第四个参数为目标柱
{if (n == 0){return;}int m;int* a_p=new int[n];//从上至下记录a柱子的盘子大小,初始为1到nfor (int i = 0; i < n; i++){a_p[i] = i + 1;//1为最小盘,0为空}int* b_p = new int[n];//从上至下记录a柱子的盘子大小,初始全为0for (int i = 0; i < n; i++)b_p[i] = 0;int* c_p = new int[n];//从上至下记录a柱子的盘子大小,初始全为0for (int i = 0; i < n; i++)c_p[i] = 0;int x , y , z;//用于记录a\b\c盘子移到第几层   x = FindTOP(a_p, n);//找到a柱的顶端y = FindTOP(b_p, n);//找到b柱的顶端z = FindTOP(c_p, n);//找到c柱的顶端while (b_p[y] != 0 || a_p[x] != 0)//a,b柱子还没搬空{x = FindTOP(a_p, n);//找到a柱的顶端y = FindTOP(b_p, n);//找到b柱的顶端z = FindTOP(c_p, n);//找到c柱的顶端int index=FindMin(a_p[x],b_p[y],c_p[z]); //比较柱顶圆盘大小switch (index){case 1:cout << a << "移动至" << b << endl; //把最小盘移动到下一个柱子上面b_p[x]= a_p[x];//更新b柱子圆盘y = x;a_p[x] = 0;//将a柱子顶端盘置空x = FindTOP(a_p, n);//找到a柱的顶端z = FindTOP(c_p, n);//找到c柱的顶端if (0<a_p[x]< c_p[z])//两个柱子不为空{cout << a << "移动至" << c << endl;c_p[x] = a_p[x];z = x;a_p[x] = 0;}else if(a_p[x] > c_p[z]>0)//两个柱子不为空{cout << c << "移动至" << a << endl;a_p[z] = c_p[z];x = z;c_p[z]=0;}else if (a_p[x] == 0&& c_p[z]!=0){cout << c << "移动至" << a << endl;a_p[z] = c_p[z];x = z;c_p[z] = 0;}else if(c_p[x] == 0 && a_p[x] != 0){cout << a << "移动至" << c << endl;c_p[x] = a_p[x];z = x;a_p[x] = 0;}case 2:cout << b << "移动至" << c << endl; //把最小盘移动到下一个柱子上面c_p[y] = b_p[y];//更新c柱子圆盘z = y;b_p[y] = 0;//将b柱子顶端盘置空x = FindTOP(a_p, n);//找到a柱的顶端y = FindTOP(b_p, n);//找到c柱的顶端if (0 < a_p[x] < b_p[y])//两个柱子不为空{cout << a << "移动至" << b << endl;b_p[x] = a_p[x];y = x;a_p[x] = 0;}else if (a_p[x] > b_p[z] > 0)//两个柱子不为空{cout << b << "移动至" << a << endl;a_p[y] = b_p[y];x = y;b_p[y] = 0;}else if (a_p[x] == 0 && b_p[y] != 0){cout << b << "移动至" << a << endl;a_p[y] = b_p[y];x = y;b_p[y] = 0;}else if (b_p[x] == 0 && a_p[x] != 0){cout << a << "移动至" << b << endl;b_p[x] = a_p[x];y = x;a_p[x] = 0;}case 3:cout << c << "移动至" << a << endl; //把最小盘移动到下一个柱子上面a_p[z] = c_p[z];//更新a柱子圆盘x = z;c_p[z] = 0;//将c柱子顶端盘置空y = FindTOP(b_p, n);//找到a柱的顶端z = FindTOP(c_p, n);//找到c柱的顶端if (0 < b_p[x] < c_p[y])//两个柱子不为空{cout << b << "移动至" << c << endl;c_p[y] = b_p[y];z = y;b_p[y] = 0;}else if (b_p[y] > c_p[z] > 0)//两个柱子不为空{cout << c << "移动至" << b << endl;b_p[z] = c_p[z];y = z;c_p[z] = 0;}else if (b_p[y] == 0 && c_p[z] != 0){cout << c << "移动至" << b << endl;b_p[z] = c_p[z];y = z;c_p[z] = 0;}else if (c_p[z] == 0 && b_p[y] != 0){cout << b << "移动至" << c << endl;c_p[y] = b_p[y];z = y;b_p[y] = 0;}}x = FindTOP(a_p, n);//找到a柱的顶端y = FindTOP(b_p, n);//找到b柱的顶端z = FindTOP(c_p, n);//找到c柱的顶端}delete[] a_p;delete[] b_p;delete[] c_p;
}
int FindMin(int a, int b, int c)//用于寻找顶端盘子最小的柱子
{if (a > 0) {//a不空if (b > c > 0) {//b\c不空if (a < c)return 1;elsereturn 3;}else if (0 < b < c) {//b\c不空if (a < b)return 1;elsereturn 2;}else if (b == 0 && c != 0) {if (a < c)return 1;elsereturn 3;}else if (c == 0 && b != 0) {if (a < b)return 1;elsereturn 2;}else if (b == 0 && c == 0)//bc空return 1;}else{//a空if (b > c > 0) {//b\c不空return 3;}else if (0 < b < c) {//b\c不空return 2;}else if (b == 0 && c != 0) {//ab空return 3;}else if (c == 0 && b != 0) {//ac空return 2;}}}
int FindTOP(int* arr,int n)//寻找顶端圆盘大小
{int i;int TOP = 0;//保存柱顶圆盘的下标for (i = 0; i < n; i++){if (arr[i] > 0) {TOP = i;break;        }}return TOP;//返回柱顶圆盘所在数组的下标}

实验截图:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Y1fsnThi-1677331824027)(assets/5564.png)]

3、 你能通过实验来比较汉诺塔问题的递归和非递归算的时间效率吗?

四.角谷猜想

对于任何正整数 n,若是偶数,则除以 2;若是奇数,则乘以 3 加上 1。这 样得到一个新的整数,如果继续进行上述处理,则最后得到的数一定是 1 吗?

1、 编写程序对 100 以内的整数进行测试验证,并找出其中最长的序列。

主函数

void main()
{int n;int arr[100];for (n = 1; n <= 100; n++) {arr[n - 1] = JiaoGu(n);}int i = FindMax(arr);cout << "序列最长的整数为" << i + 1 << endl;cout << "最长的序列长度为" << arr[i] << endl;}

角谷猜想函数

int JiaoGu(int n)
{int i = 1;//用于记录序列长度while (n != 1){if (n % 2 == 0) {n = n / 2;//偶数除以2}else {n = n * 3 + 1;//奇数乘以3加1 }i++;}return i;
}

寻找数组最大值函数

int FindMax(int a[])
{int i,temp;temp = a[0];int max=0;//保存最大值下标for (i = 1; i < 100; i++){if (a[i] > temp){temp = a[i];max = i;}}return max;
}

实验结果

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-VvBfGXDh-1677331824028)(assets/123.png)]

2、 你能给角谷问题一个肯定或否定的回答吗?

五.交通管制问题

1、 你能编程实现交通管制问题的贪心算法,对任意交叉路口的交通管制?

2、 你能证明该贪心算法的正确性吗?

3、 能根据实际的交通流量等信息,优化该贪心算法吗?

角谷猜想函数

int JiaoGu(int n)
{int i = 1;//用于记录序列长度while (n != 1){if (n % 2 == 0) {n = n / 2;//偶数除以2}else {n = n * 3 + 1;//奇数乘以3加1 }i++;}return i;
}

寻找数组最大值函数

int FindMax(int a[])
{int i,temp;temp = a[0];int max=0;//保存最大值下标for (i = 1; i < 100; i++){if (a[i] > temp){temp = a[i];max = i;}}return max;
}

实验结果

[外链图片转存中…(img-VvBfGXDh-1677331824028)]

2、 你能给角谷问题一个肯定或否定的回答吗?

五.交通管制问题

1、 你能编程实现交通管制问题的贪心算法,对任意交叉路口的交通管制?

2、 你能证明该贪心算法的正确性吗?

3、 能根据实际的交通流量等信息,优化该贪心算法吗?

HIT-哈工大数据结构-作业1(C++)相关推荐

  1. 一元多项式式计算器(哈工大数据结构实验)

    这是哈工大数据结构课的一个实验作业,试验结束了,终于可以发出来了. 实验要求: 实验 1 线性结构及其应用 实验项目:线性表的链式存储结构与应用 实验题目:一元多项式计算器 实验内容: 设计线性表的动 ...

  2. 哈工大计算机网络-作业讲解

    哈工大计算机网络作业 例题等来源于哈工大李全龙老师,李全龙老师YYDS 计算机网络笔记 我们知道分组交换网络中时延共有四种 处理时延 排队时延 传输时延 传播时延 详细讲解

  3. 数据结构作业之输出树的每一条从根节点到叶节点的路径

    数据结构作业,输出树的每一条从根节点到叶节点的路径 #include <stdio.h> #include <stdlib.h> typedef struct tree {ch ...

  4. 数据结构作业9(清览题库)

    数据结构作业9(清览题库) 主要涉及内容为:拓扑排序,关键路径,内排序等

  5. HIT暑假python作业三《超级画板》

    HIT暑假python作业三<超级画板> 作业上交版代码 编译版 程序运行效果**(运行时确保同目录下有文件夹img,里面有pen,eraser,plus,minus四个png图象,如果没 ...

  6. HIT CSAPP大作业论文

    计算机系统 大作业 题 目 程序人生-Hello's P2P 专 业 计算机类 学 号 1190201816 班 级 1903012 学 生 樊红雨 指 导 教 师 史先俊 计算机科学与技术学院 20 ...

  7. HIT计算机系统大作业2022

    计算机系统 大作业 计算机科学与技术学院 2021年5月 摘 要 学习计算机系统后,从底层对一个简单的Hello.c如何一步步编译,链接,加载,执行等进行浅层的描述. 关键词:计算机系统,底层. 目 ...

  8. HIT 计算机系统大作业 Hello程序人生P2P

    计算机系统 大作业 题 目 程序人生-Hello's P2P 专 业 人工智能(未来技术模块) 学 号 7203610725 班 级 2036014 学 生 黄鸿睿 指 导 教 师 刘宏伟 计算机科学 ...

  9. 【数据结构作业—01】用单循环链表解决约瑟夫问题

    实验作业一:线性表(链表) 1. 用单循环链表解决约瑟夫问题. 问题描述: 一个旅行社要从n个旅客中选出一名旅客,为他提供免费的环球旅行服务.旅行社安排这些旅客围成一个圆圈,从帽子中取出一张纸条,用上 ...

  10. 数据结构作业(校园导航系统)

    本人是一名暨南大学大二的学生,这是我的数据结构课程的一次编程作业,主要算法是弗洛伊德算法,希望各位大神多多指教. #include<stdio.h> #include<stdlib. ...

最新文章

  1. 独家 | 别用csv存储了-这种文件格式比csv快150倍(附链接)
  2. 洛谷P2633 Count on a tree
  3. php怎么输出3个函数和,PHP利用var_dump,var_export,print_r三个函数的区别示例
  4. 【Paper】2021_Synchronization of Resilient Complex Networks Under Attacks
  5. 为什么魂斗罗只有 128 KB却可以实现那么长的剧情?
  6. Java微信公众号开发(五)—— SVN版本控制工具
  7. 时间序列分析 lstm_LSTM —时间序列分析
  8. 初中数学抽象教学的案例_初中八年级数学上册教学视频汇总
  9. 已火 2 年,Service Mesh究竟给微服务带来了什么?
  10. spark学习-SparkSQL--07-SparkContext类和SparkConf类
  11. linux修改ip dhcp,Linux下在静态IP与动态DHCP之间切换的脚本
  12. zip安装mysql没有软件,windows10系统安装mysql-8.0.13(zip安装) 的教程详解
  13. 去找工作还要先交押金我认为不太靠谱
  14. Spring, MyBatis 多数据源的配置和管理
  15. strcpy会覆盖原来的吗_你真的会挂单吗?原来“集合竞价”10分钟竟然隐藏这么多秘密,看懂这些细节,直接精准判整日走势...
  16. 最全攻略:利用LightSeq加速你的深度学习模型
  17. SQL语句(九)使用特殊关系运算符查询
  18. OpenCV视频生成报错 Incorrect library version loaded Could not open codec ‘libopenh264‘: Unspecified error
  19. 直角四面体面积公式推导
  20. 级联选择器实现省市区三级联动

热门文章

  1. 政治正确的睡前故事(4则)【搬运】【破事水】
  2. vue3+ts+vite 路径别名配置
  3. nodejs c++ addon插件的应用场景
  4. Halcon入门(3)——回形针目标提取
  5. Warshall算法的实现(两种方式)
  6. ibm服务器显示器接口,显示器接口类型怎么选,4种主流接口要了解
  7. 及其他公共信息网络的计算机上存储,不得在未采取防护措施的情况下将互联网及其他公共信息网络上的数据复制到涉密计算机及网络,确...
  8. python 批量修改/替换数据
  9. 后序线索化二叉树及遍历(图解)
  10. mt管理器主题修改教程_微信皮肤主题怎么弄 微信设置更换修改气泡和主题教程...