python-排序(一)

冒泡排序法

bubble sort 可以说是很简单的一种排序算法了,它的思想如下.
对一个数组进行n轮迭代,每次比较相邻两个元素,如果相邻的元素
前者大于后者,就交换它们。因为直接在元素上操作而不是返回新的
数组,所以是一个inplace的操作.这里冒泡的意思其实就是每一轮冒泡
一个最大的元素就会通过不断比较和交换相邻元素使它转移到最右边
.
假如有10个小盆友从左到右站成一排,个头不等。老师想让他们按照个头
从低到高站好,于是他开始喊口号。每喊一次,从第一个小盆友开始,相邻
的小朋友如果身高不是正序就会两两交换,就这样第一轮个头最高的排到了最右边。
(冒泡到最右边)第二轮依次这么来,从第一个小朋友开始两两
交换,这样次高的小朋友又排到了倒数第二个位置。依次类推。

import random

def bubble_sort(chs):       # O(n^2), n(n-1)/2 = 1/2(n^2 + n)
    n = len(chs)
    #冒泡排序每迭代依次将最大的排序到最后一个元素位置
    # 只需要迭代n-1次,最后一次已经排序好不需要再进行排序
    for i in range(n-1):
        # 只需要迭代n-1-i次,最后已经排好的i个元素不需要再进行排序
        print(chs)
        for j in range(n-1-i):
            if chs[j] > chs[j+1]:
                chs[j],chs[j+1] = chs[j+1],chs[j]
    print(chs)
chs = list(range(10))
#shuffle()方法将序列的所有元素随机排序
random.shuffle(chs)
bubble_sort(chs)

'''
    初始无序列表:[5, 9, 4, 6, 8, 2, 7, 3, 1, 0]
    开始排序:
    [5, 4, 6, 8, 2, 7, 3, 1, 0, 9]
    [4, 5, 6, 2, 7, 3, 1, 0, 8, 9]
    [4, 5, 2, 6, 3, 1, 0, 7, 8, 9]
    [4, 2, 5, 3, 1, 0, 6, 7, 8, 9]
    [2, 4, 3, 1, 0, 5, 6, 7, 8, 9]
    [2, 3, 1, 0, 4, 5, 6, 7, 8, 9]
    [2, 1, 0, 3, 4, 5, 6, 7, 8, 9]
    [1, 0, 2, 3, 4, 5, 6, 7, 8, 9]
    [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
'''


def test_bubble_sort():
    chs = list(range(10))
    #shuffle()方法将序列的所有元素随机排序
    random.shuffle(chs)
    bubble_sort(chs)
    assert chs == sorted(chs)

选择排序

对于前者小朋友站位问题,其实还有一种思路就是,每次我们找到
最小的元素插入迭代的起始位置,这样每个位置从它自己的位置开始
它就是最小的了,一圈下来数组就有序了。选择可以理解为一个0到n-1
的迭代,每次向后查找选择一个最小的元素.
.
我们从第一个开始,从头到尾找一个个头最小的小盆友,然后把它和
第一个小盆友交换。然后从第二个小盆友开始采取同样的策略,这样
一圈下来小盆友就有序了



import random

def select_sort(seq):
    n = len(seq)
    for i in range(n-1):
        min_idx = i     # 我们假设当前下标的元素是最小的
        print(seq)
        for j in range(i+1,n):  # 从i的后边开始找最小的元素,得到它的下标
            if seq[j] < seq[min_idx]:
                min_idx = j    #一个 j 循环下来之后就找到了最小的元素的下标
        if min_idx != i:  # 一个 i 循环下来将最小值替换到最前面
            seq[i],seq[min_idx] = seq[min_idx],seq[i]
    print(seq)

seq = list(range(10))
random.shuffle(seq)
select_sort(seq)

'''
    原始列表
    [9, 3, 5, 7, 8, 2, 1, 4, 6, 0]
    开始排序
        [0, 3, 5, 7, 8, 2, 1, 4, 6, 9]
        [0, 1, 5, 7, 8, 2, 3, 4, 6, 9]
        [0, 1, 2, 7, 8, 5, 3, 4, 6, 9]
        [0, 1, 2, 3, 8, 5, 7, 4, 6, 9]
        [0, 1, 2, 3, 4, 5, 7, 8, 6, 9]
        [0, 1, 2, 3, 4, 5, 7, 8, 6, 9]
        [0, 1, 2, 3, 4, 5, 6, 8, 7, 9]
        [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
        [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
'''

def test_select_sort():
    seq = list(range(10))
    random.shuffle(seq)
    select_sort(seq)
    assert seq == sorted(seq)


插入排序

插入排序很多教科书都是用扑克牌的例子讲,想象你手里有一些扑克牌,
它们顺序是散乱的,现在需要你把它们整理成有序的,你会怎么做呢?
首先拿最顶上的一张,然后拿第二张,第二张点数大,你就把第二张
放在第一张的下边,否则放在第一张的上边。当你拿第三张的时候,你同样会找到适合它大小的位置插入进去.
.
换成小朋友一样,第一个小盆友只有一个人我们假设是有序的,然后
第二个小盆友会跟第一个比,如果第一个高就交换位置。接下来第三个
小盆友从第二个位置开始比较,如果没第二个高就交换位置,然后没
第一个高也交换位置,保持前边三个小盆友的身高有序就好。依次类推,等到最后一个小盆友也转移到合适的位置,整个队列就是有序的了。
.
插入排序就是这个道理,每次挑选下一个元素插入已经排序的数组中
初始时已排序数组只有一个元素。我们直接上代码.



import random

def insertion_sort(seq):
    '''每次挑选下一个元素插入已经排序的数组中,初始时已排序数组只有一个元素'''
    n = len(seq)
    print(seq)
    for i in range(1,n):
        value = seq[i]  #保存当前位置的值,因为转移的过程中它的位置可能被覆盖
        #找到这个值的合适位置,使得前边的数组有序 [0,i] 有序
        pos = i
        while pos > 0 and value < seq[pos-1]:
            seq[pos] = seq[pos-1]   #如果前边的元素比它大,就让它一直前移
            pos -= 1
        seq[pos] = value
        print(seq)

seq = list(range(10))
random.shuffle(seq)
insertion_sort(seq)

'''
    原始列表
    [9, 0, 2, 6, 3, 4, 8, 5, 7, 1]
    开始排序
        [0, 9, 2, 6, 3, 4, 8, 5, 7, 1]
        [0, 2, 9, 6, 3, 4, 8, 5, 7, 1]
        [0, 2, 6, 9, 3, 4, 8, 5, 7, 1]
        [0, 2, 3, 6, 9, 4, 8, 5, 7, 1]
        [0, 2, 3, 4, 6, 9, 8, 5, 7, 1]
        [0, 2, 3, 4, 6, 8, 9, 5, 7, 1]
        [0, 2, 3, 4, 5, 6, 8, 9, 7, 1]
        [0, 2, 3, 4, 5, 6, 7, 8, 9, 1]
        [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
'''

def test_insertion_sort():
    seq = list(range(10))
    random.shuffle(seq)
    sorted_seq = sorted(seq)
    insertion_sort(seq)
    assert seq == sorted_seq

猜你喜欢

转载自blog.csdn.net/qq_39469688/article/details/81533925
今日推荐