一、这几个排序网上资料挺多的,现在将几个排序的学习过程记录一下,另外这节课重点递归函数需要着重学习一下。
二、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的源码以及处理思路。