问题:一列数组,从小到大依次排序
一、选择排序
原理:
比方说有一个数组:data = [12,45,2,48,66,2,1,56,36,90,5,10,503]
从第一个数字开始,后面的数字依次与第一个比较,如果小于第一个,则和第一个交换位置。比如这里的 1 < 12,则会变成 1,45,2,48,66,2,12,56,36,90,5,10,503,这样下来,最小的会被放在第一个的位置上
然后从第二个数字开始,后面的数字依次与第二个比较,这样,倒数第二小的数字会被放在第二个位置上。
怎么写?解决两个问题:
- 要写几个for循环?
- 找出每个for循环的边界
那么,我们的选择排序要几层循环呢???答案是两层。
1、外层是往第几个位置上放元素/交换元素
i~[0,len] ##为啥从 0 开始?因为数组下标是从 0 开始
2、里层是该位置的后面的每一个元素跟其比较
j~[i+1,len]
这里我们用Python实现:
# -*- coding: utf-8 -*- #选择排序 data = [12,45,2,48,66,2,1,56,36,90,5,10,503] for i in range(len(data)): # 外层,定义第几个位置 for j in range(i+1,len(data)): # 内层,后面的每一个元素与当前外层元素相比较 #//如果后面的元素比我选择元素还小 就互换位置 if data[j] < data[i] : #互换位置 temp = data[i] data[i]=data[j] data[j] = temp print(data)
二、冒泡排序
原理:
data = [12,45,2,48,66,2,1,56,36,90,5,10,503]
比较两个相邻的比较,如果前面的比后面的大,就交换位置,一直比较,这样比较完一轮,最大的值就被放在了最后一位;
再比较,一轮,第二大的就放在了代数第二位,以此类推……
怎么写?同样解决两个 for 循环的边界
1、外层 for 循环写轮次,第一轮就是把最后一个位置确定了……
i~[0,len-1]
2、内层就是把之前的元素相比较
j~[0,len-1-i]
# -*- coding: utf-8 -*- # 冒泡排序 for i in range(len(data)-1): # 控制排好的第几个位置 for j in range(len(data)-i-1): # 控制前面的位置 # 比较左右两个值 if data[j]>data[j+1]: temp = data[j] data[j]=data[j+1] data[j+1]=temp print(data)
三、插入排序
原理:
data = [12,45,2,48,66,2,1,56,36,90,5,10,503]
相当于打扑克牌抓牌,第一张牌放手里,抓第二张,假设大于第一张就放第一张后面,以此类推……
数组内理解:把一个数组分成两部分,后面半部分就是我们要抓的牌(需要排序的元素),前面半部分就是已经排好的,也就是已经摸到手里的牌
以我们的数组来看,一开始我们抓到 12 在手里,然后去抓一张 45 ,跟 12 比较如果比 12 小就放在 12 前面,45 > 12 所以放在 12 后面,这两张就是我们手里的牌了;再继续抓一张 2 跟 45 和 12 比较,2 < 45 ,那么 45 往后挪一位,再和 12 比较, 2< 12 那么12 再往后挪一位,第一位就是 2 ;现在是 2,12,45 假设后面一个是 10 怎么办?把 10 抓过来,依次跟 45,12,10 比较,10 < 45 ,所以 45 往后挪一位到 10 的位置上,再 10 和 12 比较,10 < 12,那么 12 往后挪一位,10 到 12 的位置上,10 > 2 ,所以 2 不用挪……
for 循环也是两层:
1、外层 for 循环控制你要抓的牌
i~[0,len-1]
2、里层 for 循环是抓到的牌依次和手里的牌比较
j~[0,i-1]
# -*- coding: utf-8 -*- # 插入排序 for i in range(len(data)): # 已经抓到手里的牌 for j in range(i-1,-1): # 每次抓到手里的牌 # 如果抓到的牌大于手里的,那么手里的往后挪 if data[j]>data[i]: data[j+1] = data[j] print(data)
特殊情况:
# -*- coding: utf-8 -*- # 插入排序 for i in range(len(data)): # 控制手上已经有的数字个数 newget = data[i] # 每次新抓到的数字,如果不存起来,已有的数字后移会覆盖掉新抓到的 for j in range(i-1,-1): # 新抓的数字跟手中已有的比较 if data[j] > newget: data[j+1] = data[j] else: # 如果抓到的新数字小于最后一个,那就不用比了 break data[j+1] = newget # 不比,把新抓到的放到最后 print(data)