算法-选择、冒泡、插入

问题:一列数组,从小到大依次排序

一、选择排序

原理:

  比方说有一个数组: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,这样下来,最小的会被放在第一个的位置上

  然后从第二个数字开始,后面的数字依次与第二个比较,这样,倒数第二小的数字会被放在第二个位置上。

怎么写?解决两个问题:

  1. 要写几个for循环?
  2. 找出每个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)
原文地址:https://www.cnblogs.com/xiaowenshu/p/10126562.html