算法设计与分析实验报告python实现(排序算法、三壶谜题、交替放置的碟子、带锁的门)

一、 实验目的

1.加深学生对算法设计方法的基本思想、基本步骤、基本方法的理解与掌握;
2.提高学生利用课堂所学知识解决实际问题的能力;
3.提高学生综合应用所学知识解决实际问题的能力。

二、实验任务

1、排序算法
目前已知有几十种排序算法,请查找资料,并尽可能多地实现多种排序算法(至少实现8种)并分析算法的时间复杂度。比较各种算法的优劣。
2、三壶谜题:
有一个充满水的8品脱的水壶和两个空水壶(容积分别是5品脱和3品脱)。通过将水壶完全倒满水和将水壶的水完全倒空这两种方式,在其中的一个水壶中得到4品脱的水。
3、交替放置的碟子
我们有数量为2n的一排碟子,n黑n白交替放置:黑,白,黑,白…
现在要把黑碟子都放在右边,白碟子都放在左边,但只允许通过互换相邻碟子的位置来实现。为该谜题写个算法,并确定该算法需要执行的换位次数。
4、带锁的门:
在走廊上有n个带锁的门,从1到n依次编号。最初所有的门都是关着的。我们从门前经过n次,每次都从1号门开始。在第i次经过时(i = 1,2,…, n)我们改变i的整数倍号锁的状态;如果门是关的,就打开它;如果门是打开的,就关上它。在最后一次经过后,哪些门是打开的,哪些门是关上的?有多少打开的门?

三、实验设备及编程开发工具

实验设备:Win10电脑
开发工具:Python 3.7,Pycharm

四、实验过程设计(算法思路及描述,代码设计)

1、排序算法

(1)冒泡排序

1、比较相邻的元素。如果第一个比第二个大,就交换他们两个

2、对第0个到第n-1个数据做同样的工作。这时,最大的数就“浮”到了数组最后的位置上

3、针对所有的元素重复以上的步骤,除了最后一个

4、持续每次对越来越少的元素重复上面的步骤,直到没有任何一对数字需要比较

代码:

def BubbleSort(sums):n = len(sums)for i in range(n):for j in range(1,n - i):if sums[j - 1] > sums[j]:sums[j - 1],sums[j] = sums[j],sums[j - 1]return sumsimport random
import timeList = [random.randint(0, 100000) for i in range(5000)]
print(List)
a = time.time()BubbleSort(List)b = time.time()
print(List)
print("算法消耗时间为:",(b - a)*100,"毫秒")

冒泡排序

最好时间复杂度为O(n2),最坏时间复杂度为O(n2),平均时间复杂度为O(n^2)

img

(2)选择排序

1、在未排序序列中找到最小(大)元素,存放到排序序列的起始位置

2、再从剩余未排序元素中继续寻找最小(大)元素,然后放到已排序序列的末尾

3、以此类推,直到所有元素均排序完毕

代码:

def SelectSort(sums):n = len(sums)for i in range(0,n):min = ifor j in range(i + 1,n):if sums[j] < sums[min]:min = jsums[min],sums[i] = sums[i],sums[min]return sumsimport random
import timeList = [random.randint(0, 100000) for i in range(5000)]
print(List)
a = time.time()SelectSort(List)b = time.time()
print(List)
print("算法消耗时间为:",(b - a)*100,"毫秒")

选择排序

最好时间复杂度为O(n2),最坏时间复杂度为O(n2),平均时间复杂度为O(n^2)

img

(3)插入排序

1、从第一个元素开始,该元素可以认为已经被排序

2、取出下一个元素,在已经排序的元素序列中从后向前扫描

3、如果被扫描的元素(已排序)大于新元素,将该元素后移一位

4、重复步骤3,直到找到已排序的元素小于或者等于新元素的位置

5、将新元素插入到该位置后

6、重复步骤2~5

代码:

def InsertSort(sums):n = len(sums)for i in range(1,n):temp = sums[i]j = i - 1while j >= 0 and sums[j] > temp:sums[j + 1] = sums[j]j -= 1sums[j + 1] = tempreturn sumsimport random
import timeList = [random.randint(0, 100000) for i in range(5000)]
print(List)
a = time.time()InsertSort(List)b = time.time()
print(List)
print("算法消耗时间为:",(b - a)*100,"毫秒")

插入排序

最好时间复杂度为O(n),最坏时间复杂度为O(n2),平均时间复杂度为O(n2)

img

(4)希尔排序

1、比较相隔较远距离(称为增量)的数,使得数移动时能跨过多个元素,算法先将要排序的一组数按某个增量d分成若干组

2、对每组中全部元素进行排序,然后再用一个较小的增量对它进行,在每组中再进行排序

3、当增量减到1时,整个要排序的数被分成一组,排序完成

4、一般的初次取序列的一半为增量,以后每次减半,直到增量为1

代码:

def ShellSort(sums):n = len(sums)mid = n//2while mid >= 1:for i in range(mid,n):temp = sums[i]j = iwhile j - mid >= 0 and sums[j - mid] > temp:sums[j] = sums[j - mid]j -= midsums[j] = tempmid //= 2return sumsimport random
import timeList = [random.randint(0, 100000) for i in range(5000)]
print(List)
a = time.time()ShellSort(List)b = time.time()
print(List)
print("算法消耗时间为:",(b - a)*100,"毫秒")

希尔排序

最好时间复杂度为O(nlog n),最坏时间复杂度为O(nlogn),平均时间复杂度为O(nlogn)

img

(5)归并排序

1、申请空间,使其大小为两个已经排序序列之和,该空间用来存放合并后的序列

2、设定两个指针,最初位置分别为两个已经排序序列的起始位置

3、比较两个指针所指向的元素,选择相对小的元素放入到合并空间,并移动指针到下一位置

4、重复步骤 3 直到某一指针达到序列尾

5、 将另一序列剩下的所有元素直接复制到合并序列尾

代码:

def MergeSort(sums):if len(sums) <= 1:return sumsn = len(sums)//2left = MergeSort(sums[:n])right = MergeSort(sums[n + 1:])return Merge(left,right)def Merge(left,right):new_sums = []i,j = 0,0while i < len(left) and j < len(right):if left[i] < right[j]:new_sums.append(left[i])i += 1else:new_sums.append(right[j])j += 1new_sums = new_sums + left[i:] + right[j:]return new_sumsimport random
import timeList = [random.randint(0, 100000) for i in range(5000)]
print(List)
a = time.time()MergeSort(List)b = time.time()
print(MergeSort(List))
print("算法消耗时间为:",(b - a)*100,"毫秒")

归并排序

最好时间复杂度为O(nlogn),最坏时间复杂度为O(nlogn),平均时间复杂度为O(nlogn)

img

(6)快速排序

1、从数列中挑出一个元素作为基准数

2、分区过程,将比基准数大的放到右边,小于或等于它的数都放到左边

3、再对左右区间递归执行第二步,直至各区间只有一个数

代码:

def QuickSort(sums,left,right):if left >= right:return Falselow = lefthigh = righttemp = sums[low]while left < right:while left < right and sums[right] > temp:right -= 1sums[left] = sums[right]while left < right and sums[left] <= temp:left += 1sums[right] = sums[left]sums[right] = tempQuickSort(sums,low,left - 1)QuickSort(sums,left + 1,high)return sumsimport random
import timeList = [random.randint(0, 100000) for i in range(5000)]
print(List)
a = time.time()QuickSort(List,0,len(List) - 1)b = time.time()
print(List)
print("算法消耗时间为:",(b - a)*100,"毫秒")

快速排序

最好时间复杂度为O(nlogn),最坏时间复杂度为O(n^2),平均时间复杂度为O(nlogn)

img

(7)堆排序

1、最大堆调整:将堆的末端子节点作调整,使得子节点永远小于父节点

2、创建最大堆:将堆中的所有数据重新排序

3、堆排序:移除位在第一个数据的根节点,并做最大堆调整的递归运算

代码:

def HeapSort(sums):n = len(sums)first = n//2 - 1for start in range(first,-1,-1):HeapSort_Max(sums,start,n - 1)for end in range(n - 1,0,-1):temp = sums[end]sums[end] = sums[0]sums[0] = tempHeapSort_Max(sums,0,end - 1)return sumsdef HeapSort_Max(sums,start,end):root = startwhile True:child = 2 * root + 1if child > end:breakif child + 1 <= end and sums[child] < sums[child + 1]:child = child + 1if sums[root] < sums[child]:temp = sums[root]sums[root] = sums[child]sums[child] = temproot = childelse:breakimport random
import timeList = [random.randint(0, 100000) for i in range(5000)]
print(List)
a = time.time()HeapSort(List)b = time.time()
print(List)
print("算法消耗时间为:",(b - a)*100,"毫秒")

堆排序

最好时间复杂度为O(nlogn),最坏时间复杂度为O(nlogn),平均时间复杂度为O(nlogn)

img

(8)计数排序

1、找出待排序的数组中最大和最小的元素,新开辟一个长度为 最大值-最小值+1 的数组

2、统计原数组中每个元素出现的次数,存入到新开辟的数组中

3、根据每个元素出现的次数,按照新开辟数组中从小到大的秩序,依次填充到原来待排序的数组中,完成排序

代码:

def RadixSort(sums):Min = min(sums)Max = max(sums)List = [0 for i in range(Max - Min + 2)]for i in range(len(sums)):List[sums[i] - Min] += 1j,k = 0,0while j < (len(List)):if List[j] > 0:sums[k] = j + MinList[j] -= 1k += 1else:j += 1return sumsimport random
import timeList = [random.randint(0, 100000) for i in range(5000)]
print(List)
a = time.time()RadixSort(List)b = time.time()
print(List)
print("算法消耗时间为:",(b - a)*100,"毫秒")

计数排序

最好时间复杂度为O(n),最坏时间复杂度为O(n),平均时间复杂度为O(n)

img

2、三壶谜题

将某个时刻水壶中水的数量看作一个状态,用一个长度为3的数组表示,初始状态便为[8,0,0],再拓展他的下一结点的可能结构,若下一结点的结构已经被拓展过了便放弃,若没有拓展过则加入拓展列表中。然后递归上述操作,直到拓展列表为空或者找到目标为止。

代码:

class node: def __init__(self, data):self.data = dataself.per = None def pour(n):r_list = n.data max_list = [8, 5, 3]  for i, j in ((0, 1), (0, 2), (1, 2), (1, 0), (2, 0), (2, 1)):if r_list[i] != 0:n_list = r_list.copy()  if r_list[i] + r_list[j] > max_list[j]:n_list[i] = r_list[i] - (max_list[j] - r_list[j])n_list[j] = max_list[j]else:n_list[j] = r_list[i] + r_list[j]n_list[i] = 0flag = True for one in closed_list:if one.data == n_list:  flag = Falseif flag:print("扩展的新节点是:",n_list)new_node = node(n_list)  new_node.per = nopen_list.append(new_node)def BFS_node(root_1):  n = root_1print("当前节点:",n.data)if open_list is None:return "没有找到4品脱的水"nodelist = n.dataif 4 in nodelist:print("找到了4品脱的水")print_node(n)return "找到了4品脱的水"closed_list.append(open_list.pop(0))pour(n)print("*******")BFS_node(open_list[0])def print_node(n): if n.per == None:return ""print(n.data)print_node(n.per)# 初始化数据
root = node([8, 0, 0])
open_list = [root]  
closed_list = []
BFS_node(open_list[0])

三壶谜题:

时间复杂度为O(n^2)

img

3、交替放置的碟子

输入碟子的总数n,产生一个0,1交错的列表,其中1代表黑碟子,0代表白碟子,通过冒泡排序将碟子分开。
代码:

def Black_White(s):sums = [0 for i in range(s)]i = 0while i * 2 < s:sums[i * 2] = 1i += 1print(sums)k = 0n = len(sums)for i in range(n):for j in range(1, n - i):if sums[j - 1] > sums[j]:sums[j - 1], sums[j] = sums[j], sums[j - 1]k += 1print(sums)print("次数为:", k, "次")# 黑碟子为1,白碟子为0
Black_White(40)

交替放置的碟子:

时间复杂度为O(n^2)

img

4、带锁的门

输入门的总数n,产生两个列表表示开门和关门的状态,同过循环遍历,将各位表示反复重置,最终得到门的状态并输出。其中1表示开门,0表示关门。
代码:

# 1表示开门,0表示关门
def LockDoor(n):List = [0 for i in range(n)]List_open = []List_close = []k,s = 0,0for i in range(1,n + 1):m = n // ifor j in range(1,m + 1):if List[i * j - 1] == 0:List[i * j - 1] = 1else:List[i * j - 1] = 0for i in range(n):if List[i] == 1:List_open.append(i + 1)k += 1else:List_close.append(i + 1)s += 1print('门的状态:',List,List_open,List_close,k,s)print('开门的编号:',List_open)print('开门的数量为:', k)print('关门的编号:',List_close)print('关门的数量为:',s) LockDoor(100)

带锁的门:

时间复杂度为O(n^2)

img

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/792953.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Github 2024-04-04 开源项目日报 Top10

根据Github Trendings的统计,今日(2024-04-04统计)共有10个项目上榜。根据开发语言中项目的数量,汇总情况如下: 开发语言项目数量Python项目5TypeScript项目2Go项目1Jupyter Notebook项目1Java项目1C++项目1非开发语言项目1Vue项目1编程面试大学:成为软件工程师的全面学习计…

Spark-Scala语言实战(12)

在之前的文章中&#xff0c;我们学习了如何在spark中使用键值对中的join,rightOuterJoin,leftOuterJoin三种方法。想了解的朋友可以查看这篇文章。同时&#xff0c;希望我的文章能帮助到你&#xff0c;如果觉得我的文章写的不错&#xff0c;请留下你宝贵的点赞&#xff0c;谢谢…

攻防世界 xff_referer 题目解析

xff_referer 一&#xff1a;了解xxf和Referer X-Forwarded-For:简称XFF头&#xff0c;它代表客户端&#xff0c;也就是HTTP的请求端真实的IP&#xff0c;只有在通过了HTTP 代理或者负载均衡服务器时才会添加该项。 一般的客户端发送HTTP请求没有X-Forwarded-For头的&#xff0…

宁波ISO27001认证:信息安全管理的黄金标准

&#x1f603;宁波ISO27001认证&#xff1a;&#x1f916;信息安全管理的&#x1f4a1;黄金标准 随着信息技术&#x1f4bb;的迅猛发展&#xff0c;信息安全&#x1f50f;问题日益凸显&#xff0c;成为企业&#x1f3ec;稳定运营和持续发展的&#x1f4ca;关键因素。在这样&am…

Finite Element Procedures K.J.Bathe 【教材pdf+部分源码】|有限元经典教材 | 有限元编程

专栏导读 作者简介&#xff1a;工学博士&#xff0c;高级工程师&#xff0c;专注于工业软件算法研究本文已收录于专栏&#xff1a;《有限元编程从入门到精通》本专栏旨在提供 1.以案例的形式讲解各类有限元问题的程序实现&#xff0c;并提供所有案例完整源码&#xff1b;2.单元…

Paddle实现人脸对比

人脸对比 人脸对比&#xff0c;顾名思义&#xff0c;就是对比两个人脸的相似度。本文将用Paddle实现这一功能。 PS&#xff1a;作者肝了整整3天才稍微搞明白实现方法 数据集准备 这里使用百度AI Studio的开源数据集&#xff1a; 人脸数据_数据集-飞桨AI Studio星河社区 (b…

[C#]OpenCvSharp使用HoughCircles霍夫圆检测算法找出圆位置并计数

【效果展示】 原图&#xff1a; 找出位置&#xff1a; 【测试环境】 vs2019,netframework4.7.2,opencvsharp4.8.0 【函数用法】 cv2提供了一种圆检测的方法&#xff1a;HoughCircles。该函数的返回结果与参数设置有很大的关系。 检测的图像时9枚钱币&#xff0c;分别使用了…

特征融合篇 | 结合内容引导注意力 DEA-Net 思想 实现双主干特征融合新方法 | IEEE TIP 2024

本篇改进已集成到 YOLOv8-Magic 框架。 摘要—单幅图像去雾是一个具有挑战性的不适定问题,它从观察到的雾化图像中估计潜在的无雾图像。一些现有的基于深度学习的方法致力于通过增加卷积的深度或宽度来改善模型性能。卷积神经网络(CNN)结构的学习能力仍然未被充分探索。本文…

【算法题】换水问题 II

> 插&#xff1a;AI时代&#xff0c;程序员或多或少要了解些人工智能&#xff0c;前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。点击跳转到网站。 坚持不懈&#xff0c;越努力越幸运&#xff0c;大家…

Linux第3课 Linux系统安装及换源方法

文章目录 Linux第3课 Linux系统安装及换源方法一、VMware虚拟机下系统的安装及配置&#xff08;一&#xff09;创建新的虚拟机 二、换源三、初次配置四、修改分辨率五、共享文件夹的实现&#xff08;一&#xff09;创建并查看共享文件夹 Linux第3课 Linux系统安装及换源方法 用…

Node.js 与 webpack(四)

上一篇&#xff1a;Node.js与webpack&#xff08;三&#xff09;-CSDN博客 webpack原理 yu 优化 本章节主要介绍 Webpack 高级配置。 所谓高级配置其实就是进行 Webpack 优化&#xff0c;让我们代码在编译/运行时性能更好~ 我们会从以下角度来进行优化&#xff1a; 提升开发体…

Data-efficient Fine-tuning for LLM-based Recommendation

目录 Introduction 利用大型语言模型&#xff08;LLM&#xff09;进行推荐最近引起了相当大的关注&#xff0c;其中微调在 LLM 的适应中发挥着关键作用。然而&#xff0c;在快速扩展的推荐数据上微调LLMs的成本限制了其实际应用。为了应对这一挑战&#xff0c;小样本微调提供了…

【深入理解计算机系统第3版】有符号数和无符号数转换以及移位运算练习题2.23

题目 考虑下面的C函数&#xff1a; int fun1(unsigned word) {return (int) ((word << 24) >> 24); }int fun2(unsigned word) {return ((int) word << 24) >> 24; } 假设一个采用补码运算的机器上以32位程序来执行这些函数。还假设有符号数值的右移…

代码审计-PHP原生开发篇SQL注入数据库监控正则搜索文件定位静态分析

文章目录 前言1、Bluecms-CNVD-1Day-常规注入审计分析2、emlog-CNVD-1Day-常规注入审计分析3、emlog-CNVD-1Day-2次注入审计分析 前言 挖掘技巧&#xff1a; -语句监控-数据库SQL监控排查可利用语句定向分析 -功能追踪-功能点文件SQL执行代码函数调用链追踪 -正则搜索-(update…

QT----opencv4.8.0编译cuda版本,QTcreater使用

目录 1 编译opencv4.8.02 验证能否加载GPU cuda12.1 opencv4.8.0 vs2019 cmake3.29 1 编译opencv4.8.0 打开cmake&#xff0c;选择opencv480路径&#xff0c;build路径随意 点击configure后&#xff0c;选择这些选项&#xff0c;opencv_word&#xff0c;cuda全选&#xff0c;…

工业组态 物联网组态 组态编辑器 web组态 组态插件 编辑器

体验地址&#xff1a;by组态[web组态插件] BY组态是一款非常优秀的纯前端的【web组态插件工具】&#xff0c;可无缝嵌入到vue项目&#xff0c;react项目等&#xff0c;由于是原生js开发&#xff0c;对于前端的集成没有框架的限制。同时由于BY组态只是一个插件&#xff0c;不能独…

【Linux】Ubuntu 文件权限管理

Linux 系统对文件的权限有着严格的控制&#xff0c;用于如果相对某个文件执行某种操作&#xff0c;必须具有对应的权限方可执行成功&#xff0c;这也是Linux有别于Windows的机制&#xff0c;也是基于这个权限机制&#xff0c;Linux可以有效防止病毒自我运行。因为运行的条件是必…

【接口】HTTP(1)|请求|响应

1、概念 Hyper Text Transfer Protocol&#xff08;超文本传输协议&#xff09;用于从万维网&#xff08;就是www&#xff09;服务器传输超文本到本地浏览器的传送协议。 HTTP协议是基于TCP的应用层协议&#xff0c;它不关心数据传输的细节&#xff0c;主要是用来规定客户端和…

详解python中的迭代

如果给定一个list或tuple&#xff0c;我们可以通过for循环来遍历这个list或tuple&#xff0c;这种遍历我们称为迭代&#xff08;Iteration&#xff09;。 在Python中&#xff0c;迭代是通过for ... in来完成的&#xff0c;而很多语言比如C语言&#xff0c;迭代list是通过下标完…

4月4号总结

java学习 一.接口 1.介绍 定义接口需要使用到关键字interface去定义接口。 格式如下&#xff1a; 类与接口的关系不是继承&#xff0c;而是实现&#xff0c;用关键字 implements &#xff0c;格式如下&#xff1a; 这个类去实现接口&#xff0c;其中的关系就相当于&#xf…