快速排序
思路:
1.取第一个元素,是其归位(排到正确的位置)
2.列表被分为两部分,左边都比第一个元素小,右边都比其大
3.依次归位
首先排第一个数
def partition(li, left, right):
tmp = li[left] # 腾出一个空位
while left < right: # 有可排序的列表
while left < right and li[right] >= tmp: # 从右边找比tmp小的数
right -= 1 # 若比tmp大则右边的指针向左移一位
li[left] = li[right] # 找到的比tmp小的数放到左边的空位上
print(li)
while left < right and li[left] <= tmp: # 右边有了一个空位,则须从左侧空位后的数找比tmp大的移到右侧空位上
left += 1 # 若比tmp小需要向右移一位
li[right] = li[left] # 找到的比tmp大的数放到右侧空位上
print(li)
li[left] = tmp # 当左侧都比tmp小,右侧都比tmp大,将tmp归位
li = [8, 7, 9, 5, 4, 2, 6, 1, 3]
print(li)
partition(li, 0, len(li)-1)
print(li)
将第一个元素排到正确的位置:
[8, 7, 9, 5, 4, 2, 6, 1, 3]
[3, 7, 9, 5, 4, 2, 6, 1, 3]
[3, 7, 9, 5, 4, 2, 6, 1, 9]
[3, 7, 1, 5, 4, 2, 6, 1, 9]
[3, 7, 1, 5, 4, 2, 6, 1, 9]
[3, 7, 1, 5, 4, 2, 6, 8, 9]
找到第一个元素的正确排序位置后,其他元素以此类推
def partition(li, left, right):
tmp = li[left] # 腾出一个空位
while left < right: # 有可排序的列表
while left < right and li[right] >= tmp: # 从右边找比tmp小的数
right -= 1 # 若比tmp大则右边的指针向左移一位
li[left] = li[right] # 找到的比tmp小的数放到左边的空位上
while left < right and li[left] <= tmp: # 右边有了一个空位,则须从左侧空位后的数找比tmp大的移到右侧空位上
left += 1 # 若比tmp小需要向右移一位
li[right] = li[left] # 找到的比tmp大的数放到右侧空位上
li[left] = tmp # 当左侧都比tmp小,右侧都比tmp大,将tmp归位
return left
def quick_sort(li, left, right):
if left < right:
mid = partition(li, left, right) # 找到第一个元素的正确位置
quick_sort(li, left, mid-1)
quick_sort(li, mid+1, right)
li = [8, 7, 9, 5, 4, 2, 6, 1, 3]
quick_sort(li, 0, len(li) - 1)
print(li)
快速排序的时间复杂度:O(nlogn)
最坏的情况(列表是从大到小排序的,每次取一个数,该数都是这趟比较的最大值,要对比n*n次):O(n²)
穿插小知识
对快速排序计时
def _quick_sort(li, left, right):
if left < right:
mid = partition(li, left, right) # 找到第一个元素的正确位置
_quick_sort(li, left, mid - 1)
_quick_sort(li, mid + 1, right)
@cal_time
def quick_sort(li):
_quick_sort(li, 0, len(li) - 1)
li = list(range(10000))
random.shuffle(li)
quick_sort(li)
print(li)
对比快速排序和冒泡排序所用时长
li = list(range(10000))
random.shuffle(li)
li1 = copy.deepcopy(li)
li2 = copy.deepcopy(li)
quick_sort(li1)
bubble_sort(li2)
print(li1)
print(li2)
结果:
quick_sort spend_time: 0.015805959701538086 secs.
bubble_sort spend_time: 4.075677156448364 secs.
copy与deepcopy
copy只拷贝了列表中元素的地址
deepcopy复制了一个全新的变量,与之前变量相同