第14章 算法-浙江高中信息技术知识点

2024-10-09
| 18页
| 129人阅读
| 10人下载
教辅
宁波诸事皆成教育科技有限公司
进店逛逛

资源信息

学段 高中
学科 信息技术
教材版本 -
年级 高三
章节 -
类型 学案-知识清单
知识点 -
使用场景 高考复习
学年 2024-2025
地区(省份) 浙江省
地区(市) -
地区(区县) -
文件格式 PDF
文件大小 1.46 MB
发布时间 2024-10-09
更新时间 2024-10-09
作者 宁波诸事皆成教育科技有限公司
品牌系列 -
审核时间 2024-10-09
下载链接 https://m.zxxk.com/soft/47832719.html
价格 3.00储值(1储值=1元)
来源 学科网

内容正文:

浙江高中技术培优算法(陶小波) 64 第十四章 算法 1. 算法效率,同一个问题会有可能有不同的解决办法,也就是说可能有不 同的算法,就如同“一题多解”一样。有的算法效率高一些,有的算法效率低一 些。通常,算法效率的高低可由算法复杂度来度量。算法复杂度又分为时间复杂 度和空间复杂度,时间复杂度反映算法执行所需要的时间,空间复杂度反映算法 复杂度所需要占用的存储空间,每个算法的复杂度都不是固定的。 2. 常见的时间复杂度的耗时比较:O(1)<=O(log2n)<=O(n)<=O(n²) 如下图 所示 常见算法复杂度 算法名 复杂度 解析 O(1) 枚举、递归 O(n) 冒泡排序、选择排序 O(n²) 对分查找法 O(log2n) (一)递归 递归需要满足两个条件 1.确定递归公式、2.递归结束条件 递归通过对递归工作栈的压栈和出栈操作实现计算 例如:求 5! def f(x): If x==1: #结束条件 return 1 else: return f(x-1)*x #递归公式 计算过程: f(5)=f(4)*5 递归工作栈中入栈*5 f(4)=f(3)*4 递归工作栈中入栈*4 f(3)=f(2)*3 递归工作栈中入栈*3 f(2)=f(1)*2 递归工作栈中入栈*2 f(1)=1 递归工作栈中入栈 1 根据栈的原理,出栈顺序为 1、*2、*3、 *4 和*5,最后计算得 120 【仅供参考】 (二)排序 考纲中的排序包括冒泡排序,选择排序。但是在实际解题中还会碰到其他排序, 例如桶排序、插入排序、选择排序、索引排序及冒泡排序的优化。本文将针对冒 泡、选择、插入、选择排序、桶排序、索引排序及冒泡排序优化进行分析。 升序排:从小到大排序,降序排:从大到小排序 浙江高中技术培优算法(陶小波) 65 (1) 冒泡排序 冒泡排序算法是把较小的元素往前调或者把较大的元素往后调。这种方法主要是 通过对相邻两个元素进行大小的比较,根据比较结果和算法规则对该二元素的位 置进行交换,这样逐个依次进行比较和交换,就能达到排序目的。冒泡排序比较 次数(n*(n-1))/2 有如下公共代码: import random ls=[] n=5 for i in range(n): ls.append(random.randint(10,100)) for i in range(n-1): for j in range(n-1,i,-1): if ls[j]>ls[j-1]: ls[j],ls[j-1]=ls[j-1],ls[j] 降序排(从后往前冒泡) for i in range(n-1): for j in range(n-1,i,-1): if ls[j]<ls[j-1]: ls[j],ls[j-1]=ls[j-1],ls[j] 升序排(从后往前冒泡) for i in range(n-1): for j in range(0,n-i-1): if ls[j]>ls[j+1]: ls[j],ls[j+1]=ls[j+1],ls[j] 升序排(从前往后冒泡) for i in range(n-1): for j in range(1,n-i): if ls[j]>ls[j-1]: ls[j],ls[j-1]=ls[j-1],ls[j] 降序排(从前往后冒泡) for i in range(n-1): flag=False for j in range(n-1,i,-1): if ls[j]>ls[j-1]: ls[j],ls[j-1]=ls[j-1],ls[j] Flag=True If flag==False: break 冒泡优化 1 k = n - 1 last = 0 for i in range(n - 1): flag = True for j in range(k): if ls[j] > ls[j + 1]: ls[j],ls[j+1]=ls[j+1],ls[j] last = j flag = False k = last if flag: break 冒泡优化 2 浙江高中技术培优算法(陶小波) 66 (2) 选择排序 选择排序是给每个位置选择当前元素最小的,比如给第一个位置选择最小的,在 剩余元素里面给第二个元素选择第二小的,依次类推,直到第 n-1 个元素,第 n 个元素不用选择了。 有如下公共代码: import random ls=[] n=5 for i in range(n): ls.append(random.randint(10,100)) (3) 桶排序 桶排序 (Bucket sort)或所谓的箱排序,是一个排序算法,工作的原理是将数 组分到有限数量的桶子里。每个桶子再个别排序(有可能再使用别的排序算法 或是以递归方式继续使用桶排序进行排序)。。 n=10 ls=[random.randint(1,100) for i in range(n)]#生成随机数 bucket=[0]*101 #新建一个范围在[0,100]之间的桶 for i in ls:#入桶 bucket[i]+=1 for i in range(1,100):#出桶 for j in range(bucket[i]): print(i,end=",") for i in range(n-1): k=i for j in range(i+1,n): if ls[j]<ls[k]: k=j if k!=i: ls[k],ls[i]=ls[i],ls[k] 选择排序写法 1 for i in range(n-1): for j in range(i+1,n): if ls[i]>ls[j]: ls[i],ls[j]=ls[j],ls[i] 选择排序写法 2 浙江高中技术培优算法(陶小波) 67 (4) 插入排序 插入排序,一般也被称为直接插入排序。对于少量元素的排序,它是一个有效 的算法 。插入排序是一种最简单的排序方法,它的基本思想是将一个记录插入 到已经排好序的有序表中,从而一个新的、记录数增 1 的有序表。在其实现过 程使用双层循环,外层循环对除了第一个元素之外的所有元素,内层循环对当 前元素前面有序表进行待插入位置查找,并进行移动 import random j = 0 n = 5 a=[random.randint(1,100) for i in range(n)]#生成随机数 for i in range(0,n): key = a[i] j = i - 1 while j >= 0 and key < a[j]: a[j+1] = a[j] j = j - 1 a[j+1]= key (5) 插入排序(写法 2) import random n = 5 a=[random.randint(1,100) for i in range(n)]#生成随机数 for i in range(n): key = a[i] for j in range(i-1,-2,-1): if key >= a[j]: break else: a[j + 1] = a[j] a[j + 1] = key print(a) 浙江高中技术培优算法(陶小波) 68 (6) 索引排序 索引排序,是基于冒泡排序法的一种优化算法,算法核心是:用一个数组元素的 值 做 另 一 个 数 组 元 素 的 下 标 , 然 后 交 换 下 标 。 例 如 a[b[1]]<a[b[2]] :t=b[1]:b[1]=b[2]:b[2]=t。代码如下: import random n=10 ls=[random.randint(1,100) for i in range(n)]#生成随机数 xb=[i for i in range(n)] for i in range(n-1): for j in range(n-1,i,-1): if ls[xb[j]]>ls[xb[j-1]]: xb[j],xb[j-1]=xb[j-1],xb[j] for i in range(n): print(ls[xb[i]]) (7) 易考点 a相同根据 b排序 ls=[['A',2,0],['C',1,1],['F',3,1],['C',0,1]] for i in range(len(ls)-1): for j in range(len(ls)-1,i,-1): if ls[j][1]>ls[j-1][1] or (ls[j][1]==ls[j-1][1] and ls[j][2]<ls[j-1][2]): ls[j],ls[j-1]=ls[j-1],ls[j] #二维数组要整个交换 print(ls) 排序数组中的其中一段 #flag=-1 降序,flag=1 升序 def sorts(ls,st,ed,flag): for i in range(st,ed): for j in range(ed,i,-1): if ls[j]*flag>ls[j-1]*flag: ls[j],ls[j-1]=ls[j-1],ls[j] return ls ls=[1,3,2,4,5,7,9,8,0,6] print(sorts(ls,0,9,-1)) 浙江高中技术培优算法(陶小波) 69 (8) 计数排序(求最值) import random n = 5 a=[random.randint(1,100) for i in range(n)]#生成随机数[82, 43, 60, 27, 30] ls=[0]*n for i in range(n): for j in range(n): if a[i]<a[j]: ls[i]+=1 print(a) so=[] k=0 while len(so)!=len(a): if ls[k] == max(ls): so.append(a[k]) ls[k]=-1 k=(k+1)%len(a) print(so)#排序后的结果 for i in range(len(ls)): if ls[i]==len(ls)-1: print("最小值是",a[i]) if ls[i] == 0: print("最大值是", a[i]) 浙江高中技术培优算法(陶小波) 70 (9) 快速排序(递归版本) def partition(arr, low, high): i = (low - 1) pivot = arr[high] for j in range(low, high): if arr[j] <= pivot: i = i + 1 arr[i], arr[j] = arr[j], arr[i] arr[i + 1], arr[high] = arr[high], arr[i + 1] return i + 1 def quickSort(arr, low, high): if low < high: pi = partition(arr, low, high) quickSort(arr, low, pi - 1) quickSort(arr, pi + 1, high) arr = [10, 7, 8, 9, 1, 5] n = len(arr) quickSort(arr, 0, n - 1) print("排序后的数组:") for i in range(n): print(arr[i]) 浙江高中技术培优算法(陶小波) 71 (三)查找算法 (1) 顺序查找最后一个 对于任意一个序列以及一个给定的元素,将给定元素与序列中元素依次比较,直 到找出与给定关键字相同的元素,或者将序列中的元素与其都比较完为止。 例如有 20 个数 最优的情况是第一个就找到了 即查找一次 最坏的情况 最后一 个才找到 即找了 20 次 ,下面代码就是标准的顺序查找算法功能是找到的是最 后一个等于 Key 的位置,并用变量 k记录。用 flag 表示是否查找到过该数 import random n=20 #待查找的数的总数 key=random.randint(1,50) #生成待查找的数 key ls=[random.randint(1,50) for i in range(n)] flag=False#是否查找到 key‘’ k=-1 #记录位置 for i in range(len(ls)): if ls[i]==key: flag=True k=i if flag: print("查找到 key 的位置在",k) else: print("查无此数") (2) 顺序查找第一个 在顺序查找中,还有一个比较特殊的存在,即查找第一个,例如有列表[1,2,2,2] 需要通过顺序查找法,查找到第一个 2,那么就需要在代码中控制,当第一次出 现 2时,就立马 break 出当前循环,代码如下 import random n=20 #待查找的数的总数 key=random.randint(1,50) #生成待查找的数 key ls=[random.randint(1,50) for i in range(n)] flag=False#是否查找到 key for i in range(len(ls)): if ls[i]==key: flag=True break if flag: print("查找到 key 的位置在",i) else: print("查无此数") 浙江高中技术培优算法(陶小波) 72 对分查找 对分查找首先将查找键与有序数组内处于中间位置的元素进行比较,如果中间位 置上的元素内的数值与查找键不同,根据数组元素的有序性,就可确定应该在数 组的前半部分还是后半部分继续进行查找;在新确定的范围内,继续按上述方法 进行查找,直到获得最终结果。 对分查找有如下性质: 1. 对分查找法要求待查找的数组值是有序等。 2. 对分查找法最多比较次数为 ���2(�) + 1 3. 对分查找法平均比较次数为 (1) 标准对分代码写法 import random n=10#数的总数 ls=[random.randint(20,40) for i in range(n)]#生成随机数 ls.sort() #对数组进行升序排序 key=33 #待查找的数(例如查找 33) i,j,m,flag=0,n-1,0,False #i:起始位置游标,j:终止位置游标,m:当前对分到的位置,flag:是否查找到该 值 while i<=j and flag==False: m=(i+j)//2 if ls[m]==key: flag=True break elif ls[m]>key: j=m-1 else: i=m+1 if flag: print("查找到该值,位置为",m) else: print("查无此数") 浙江高中技术培优算法(陶小波) 73 例如:有数组长度为 10 的列表 其中值分别为 21, 25, 26, 29, 31, 33, 35, 37, 38, 39 通过对分查找算法查找 33,对应的 i,j,m,flag 的变化如表 1所示 初值 第一次 第二次 第三次 m=0 m=4 m=7 m=5 i=0 i=5 i=5 i=5 j=9 j=9 j=6 j=6 flag=false flag=false flag=false flag=true:循环 退出 表 1 当然,对分查找法与数据结构中的二叉树思想一致,所以我们也可以用二叉树来 表示对分查找算法的对分过程。如下图 浙江高中技术培优算法(陶小波) 74 (2) 标准对分查找变式 import random n=10#数的总数 ls=[random.randint(20,40) for i in range(n)]#生成随机数 ls.sort() #对数组进行升序排序 key=33 #待查找的数 i,j,m=0,n-1,0 #i:起始位置游标,j:终止位置游标,m:当前对分到的位置,flag:是否查找到该 值 while i<=j : m=(i+j)//2 if ls[m]==key: break elif ls[m]>key: j=m-1 else: i=m+1 if i<=j: print("查找到该值,位置为",m) else: print("查无此数") 如上述代码所示,变式和原式区别在于 变式去掉的用来标识有没有找到 key 的 flag 变量 计算可得 当 key 在当前数组 ls 中不存在时 i>j 即 i=j+1 ,当 key 存在于数组 中时 i<=j,所以在循环结束后 我们可以 通过 i和 j的关系来判断 key 是否存 在。 浙江高中技术培优算法(陶小波) 75 (3) 求大于等于 key 的第一个数 n=10#数的总数 ls=[1,2,2,2,2,2,2,2,2,3] key=2 i,j,m=0,n-1,0 #i:起始位置游标,j:终止位置游标,m:当前对分到的位置,flag:是否查找到该 值 while i<=j : m=(i+j)//2 if ls[m]>=key: j=m-1 else: i=m+1 print("连续数的第一个位置是",i) 如上述代码所示,变式和原式区别在于 变式去掉的用来标识有没有找到 key 的 flag 变量以及去掉了找到后退出的代码 即去掉了 break。 设 key 为 2 时 当 key 等于 ls[m]时,j 要往前走,一直走到第一个不是 2的位置, 即当前 1的位置时,i往后走 1,即 i=1,所以第一个数的位置是 i 初值 第一轮 第二轮 第三轮 m 0 4 1 0 i 0 0 0 1 j 9 3 0 0 浙江高中技术培优算法(陶小波) 76 (4) 求小于等于 key 的最后一个数 n=10#数的总数 ls=[1,2,2,2,2,2,2,2,2,3] key=2 i,j,m=0,n-1,0 #i:起始位置游标,j:终止位置游标,m:当前对分到的位置,flag:是否查找到该 值 while i<=j : m=(i+j)//2 if ls[m]>key: j=m-1 else: i=m+1 print("连续数的最后一个位置是",j) 如上述代码所示,变式和原式区别在于 变式去掉的用来标识有没有找到 key 的 flag 变量以及去掉了找到后退出的代码 即去掉了 break 表 3 设 key 为 2 时 当 key 等于 ls[m]时,i 要往后走,一直走到第一个不是 2的位置, 即当前 3的位置时,j往前走 1,即 j=8,所以最后一个数的位置是 j 初值 第一轮 第二轮 第三轮 第四轮 m 0 4 7 8 9 i 0 5 8 9 9 j 9 9 9 9 8 浙江高中技术培优算法(陶小波) 77 (5) 根据对分次数求 key 例:有如下代码,当 c等于 2的时候,key 有可能是多少? import random c=0 n=10#数的总数 ls=[random.randint(20,40) for i in range(n)]#生成随机数 ls.sort() #对数组进行升序排序 key=random.randint(20,40)#待查找的数 i,j,m,flag=0,n-1,0,False #i:起始位置游标,j:终止位置游标,m:当前对分到的位置,flag:是否查找到该 值 while i<=j and flag==False: c+=1 m=(i+j)//2 if ls[m]==key: flag=True break elif ls[m]>key: j=m-1 else: i=m+1 if flag: print("查找到该值,位置为",m) else: print("查无此数") 解:例如有数组长度为 10 的列表 其中值分别为 21, 25, 26, 29, 31, 33, 35, 37, 38, 39,通过画二分判定树(如下),可以很显然看到 c=2 的时候 就是对分 2次,即 key 有可能是 25 或 37 浙江高中技术培优算法(陶小波) 78 (6) 根据 i、j 变换求 key 例:有如下代码,当 c等于 1的时候,key 有可能是多少? import random c=0 n=10#数的总数 ls=[random.randint(20,40) for i in range(n)]#生成随机数 ls.sort() #对数组进行升序排序 key=random.randint(20,40)#待查找的数 i,j,m,flag=0,n-1,0,False #i:起始位置游标,j:终止位置游标,m:当前对分到的位置,flag:是否查找到该 值 while i<=j and flag==False: m=(i+j)//2 if ls[m]==key: flag=True break elif ls[m]>key: j=m-1 c-=1 else: i=m+1 c+=1 if flag: print("查找到该值,位置为",m) else: print("查无此数") 解:例如有数组长度为 10 的列表 其中值分别为 21, 25, 26, 29, 31, 33, 35, 37, 38, 39,通过画二分判定树(如下),可以很显然看到 c=1 的时候 key 有可 能是 37 或 29 或 35 浙江高中技术培优算法(陶小波) 79 (7) 常见二分查找错误写法 有公共代码: n=10#数的总数 ls=[1,2,3,4,5,6,7,8,9,10] key=3 #待查找的数(例如查找 33) i,j,m=0,n-1,0 #i:起始位置游标,j:终止位置游标,m:当前对分到的位置 while i<=j : m=(i+j+1)//2 if ls[m]==key: break elif ls[m]>key: j=m-1 else: i=m 正确可以使用 while i<j : m=(i+j+1)//2 if ls[m]==key: break elif ls[m]>key: j=m-1 else: i=m 查询部分值位置正确,查询最左边的值 位置不正确 while i<j : m=(i+j)//2 if ls[m]==key: break elif ls[m]>key: j=m-1 else: i=m 循环可以进行,但位置查询不正确 while i<j : m=(i+j-1)//2 if ls[m]==key: break elif ls[m]>key: j=m else: i=m+1 查询部分值位置正确,查询最右边的值 位置不正确 while i<=j : m=(i+j-1)//2 if ls[m]==key: break elif ls[m]>key: j=m else: i=m+1 死循环 浙江高中技术培优算法(陶小波) 80 (8) 二分判定树绘制 有代码如下,其绘制判定树的办法是 ls=[22,33,44,55,66,77,88] i,j,m=0,6,0 while i<=j : m=(i+j)//2 if ls[m]==key: break elif ls[m]>key: j=m-1 else: i=m+1 第一步:确定中间位置(因为 i=0,j=6,可以推算出 m=3,即值为 55) 第二步:确定 55 左子树位置(因为 i=0,j=2,可以推算出 m=1,即值为 33) 第三步:确定 55 右子树位置(因为 i=4,j=6,可以推算出 m=5,即值为 77) 第四步:确定 33 左子树位置(因为 i=0,j=0,可以推算出 m=0,即值为 22) 浙江高中技术培优算法(陶小波) 81 第五步:确定 33 右子树位置(因为 i=2,j=2,可以推算出 m=2,即值为 44) 第六步:确定 77 左子树位置(因为 i=4,j=4,可以推算出 m=4,即值为 66) 第七步:确定 77 右子树位置(因为 i=6,j=6,可以推算出 m=6,即值为 88) 完成

资源预览图

第14章 算法-浙江高中信息技术知识点
1
第14章 算法-浙江高中信息技术知识点
2
第14章 算法-浙江高中信息技术知识点
3
第14章 算法-浙江高中信息技术知识点
4
所属专辑
相关资源
由于学科网是一个信息分享及获取的平台,不确保部分用户上传资料的 来源及知识产权归属。如您发现相关资料侵犯您的合法权益,请联系学科网,我们核实后将及时进行处理。