【笨办法学python 进阶版】【ex16_bubble+merge+quick】笨办法实现--bubble_sort+merge_sort+quick_sort

一、这几个排序网上资料挺多的,现在将几个排序的学习过程记录一下,另外这节课重点递归函数需要着重学习一下。
二、pycharm的python3.8.3环境
可以先用处理list的思路进行写,然后在考虑链表的处理方式
现将作者zed的测试脚本拷贝如下:
0、test_sorting.py

import sorting
from dllist import DoubleLinkedList
from random import randint

max_number = 30

def random_list(count):
    numbers = DoubleLinkedList()
    for i in range(count, 0, -1):
        numbers.shift(randint(0, 10000))
    return numbers

def is_sorted(numbers):
    node = numbers.begin
    while node and node.next:
        if node.value > node.next.value:
            return False
        else:
            node = node.next
    return True

def test_bubble_sort():
    numbers = random_list(10)
    sorting.bubble_sort(numbers)
    assert is_sorted(numbers)
# test_bubble_sort()

def test_merge_sort():
    numbers = random_list(max_number)
    sorting.merge_sort(numbers)
    assert is_sorted(numbers)

1、冒泡排序:
处理思路:拿其中一个值,去和整个list的值进行比对,最简单的就是两个for循环的嵌套,但是可以优化一下:

bubble_sort.py

def bubble_sort(testlist):
###从testlist中第i个元素开始和i+1位置开始的元素进行比较,
# 如果第i位的元素大于第i+1位置的元素的时候,i和j位置元素互换
#一直比较到n-1位元素,因为n-1和n-1+1(也就是最后一个元素)比较
    for i in range(len(testlist)-1):
        for j in range(i+1, len(testlist)):
            if testlist[i] > testlist[j]:
                testlist[i], testlist[j] = testlist[j], testlist[i]
    return testlist

testlist = [54,26,93,17,77,31,44,55,20]
print('sorted:', bubble_sort(testlist))

作者zed的方法基本在书中写的差不多了,
主要是有一个判断is_sorted进行判断
bubble_sort.py

def is_sorted(numbers):
    node = numbers.begin
    while node and node.next:
        if node.value > node.next.value:
            return False
        else:
            node = node.next
    return True

def bubble_sort(number):

    number.dump()
    while True:
        node = number.begin
        while node.next:
            if node.value > node.next.value:
                node.value, node.next.value = node.next.value, node.value
            node = node.next
        if is_sorted(number):
            break
    number.dump()

2、归并排序
按照作者zed的“自上而下”的版本直接就写出来:

def merge_sort(testlist):
#def merge_sort(list m):
    #if length of m <=1 then
    ##return m,确保只有一个元素的时候才会有返回,不然还会一直执行下去
    ###递归函数需要有return才可以执行结束
    if len(testlist) <=1:
        return testlist
    ##for each x with index i in m do
    ## if i < len(length of m)/2 then
    ## add x to left
    ## else:add x to right
    mid = len(testlist) // 2
    left = testlist[:mid]
    right = testlist[mid:]

    left = merge_sort(left)
    right = merge_sort(right)

    return merge(left, right)

def merge(left, right):

    result = []
    while left and right:
        if left[0] <= right[0]:
            result.append(left[0])
            left.pop(0)
        else:
            result.append(right[0])
            right.pop(0)
    ##这里判断不能用if,不然有可能遗漏数据
    while left:
        result.append(left[0])
        left.pop(0)
    while right:
        result.append(right[0])
        right.pop(0)

    return result

3、快速排序
wiki给的伪代码
Sorting the entire array is accomplished by quicksort(A, 0, length(A) - 1)

algorithm quicksort(A, lo, hi) is
    if lo < hi then
        p := partition(A, lo, hi)
        quicksort(A, lo, p - 1)
        quicksort(A, p + 1, hi)

algorithm partition(A, lo, hi) is
    pivot := A[hi]
    i := lo
    for j := lo to hi do
        if A[j] < pivot then
            swap A[i] with A[j]
            i := i + 1
    swap A[i] with A[hi]
    return i

按照上面的代码一步一步写就好了,关键是找到要排序的元素插入点i,然后分为(lo, i-1), (i+1, hi),在插入点把list分为两段来处理:
quick_sort.py

def quick_sort(A, lo, hi):
    if lo < hi:
        p = partition(A, lo, hi)
        quick_sort(A, lo, p-1)
        quick_sort(A, p+1, hi)

def partition(A, lo, hi):
    pivot = A[hi]
    i = lo

    for j in range(lo, hi):
        if A[j] < pivot:
            A[i], A[j] = A[j], A[i]
            i += 1
    A[i], A[hi] = A[hi], A[i]
    return i

说明
1、《笨办法学python 进阶版》作者链接:https://learncodethehardway.org/more-python-book/
作者github:https://github.com/zedshaw/learn-more-python-the-hard-way-solutions
可以看一下zed的源码以及处理思路。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值