一、快速排序
快速排序的思路:
1、对于列表li,第一次取一个元素P(第一个元素或倒数第一个元素),使元素归位
排序前:
[3, 5, 8, 1, 2, 9, 4, 7, 6]
2、通过算法函数将P分成两部分,左部分都比P小,右部分都比P大
6归位后:
[3, 5, 4, 1, 2, 6, 9, 7, 8]
3、将列表的左边部分[3, 5, 4, 1, 2],右边部分[9, 7, 8]进行递归调用归位,即可完成排序
排序后:
[1, 2, 3, 4, 5, 6, 7, 8, 9]
1、归位算法函数
思路
1、取列表倒数一个元素,暂存tmp变量,此时列表倒数第一个位置为空
2、取变量left=0,从列表左边开始遍历列表,判断当前的数是否小于tmp,如果小于则继续往右走,如果大于tmp,则将当前的数移存到right
3、取变量right=列表长度。从列表右边开始倒序遍历列表,判断当前的数是否大于tmp,如果大于则继续往左走(right-1),如果小于tmp,则将当前的数移存到left,当前数的当前位置为空
4、直到left=right时即完成归位
def _homing(li, left, right):
tmp = li[right] # 暂存倒数第一个数到tmp
while left < right: # 结束条件
# 此时右边有空位,则从左边开始遍历,找寻大于tmp的数
while left < right and li[left] <= tmp:
left += 1
li[right] = li[left] # 循环完后,此时li[left]>tmp ,则将li[left]移存li[right]
# 此时左边有空位,则从右边开始遍历,找寻小于tmp的数
while left < right and li[right] >= tmp:
right -= 1
li[left] = li[right] # 循环完后,此时li[right]<tmp ,则将li[right]移存li[left]
li[left] = tmp # 当left=right时,循环结束,此时将tmp归位至li[left]
return left
2、递归完成排序
def _quick_sort(li, left, right):
if left < right:
mid = _homing(li, left, right) # 第一次归位将li分成左右部分,返回中间数的下标
_quick_sort(li, left, mid - 1) # 将左边部分进行归位
_quick_sort(li, mid + 1, right) # 将右边部分进行归位
li = [3, 5, 8, 1, 2, 9, 4, 7, 6]
_quick_sort(li, 0, len(li)-1)
print(li)
# 结果
[1, 2, 3, 4, 5, 6, 7, 8, 9]
时间复杂度
最好情况:O(nlogn)
最坏情况:O(n²)
3、相比冒泡排序
import copy
import time
import sys
import random
sys.setrecursionlimit(100000)
def cal_time(func):
def inner(*args, **kwargs):
strat = time.time()
result = func(*args, **kwargs)
end = time.time()
print('%s执行时间:%s' % (func.__name__, end - strat))
return result
return inner
def _homing(li, left, right):
tmp = li[right] # 暂存倒数第一个数到tmp
while left < right: # 结束条件
# 此时右边有空位,则从左边开始遍历,找寻大于tmp的数
while left < right and li[left] <= tmp:
left += 1
li[right] = li[left] # 循环完后,此时li[left]>tmp ,则将li[left]移存li[right]
# 此时左边有空位,则从右边开始遍历,找寻小于tmp的数
while left < right and li[right] >= tmp:
right -= 1
li[left] = li[right] # 循环完后,此时li[right]<tmp ,则将li[right]移存li[left]
li[left] = tmp # 当left=right时,循环结束,此时将tmp归位至li[left]
return left
def _quick_sort(li, left, right):
if left < right:
mid = _homing(li, left, right) # 第一次归位将li分成左右部分,返回中间数的下标
_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)
# 以上是快速排序
# 以下的冒泡排序
@cal_time
def bubble_sort(li):
for i in range(len(li) - 1):
exchange = False
for j in range(len(li) - i - 1):
if li[j] > li[j + 1]:
li[j], li[j + 1] = li[j + 1], li[j]
exchange = True
# print("第%s趟" % i, li)
if exchange is False:
return
li = list(range(10000, 0, -1))
random.shuffle(li)
li1 = copy.deepcopy(li)
li2 = copy.deepcopy(li)
quick_sort(li1)
bubble_sort(li2)
print(li1)
print(li2)
结果:
quick_sort执行时间:0.015630722045898438
bubble_sort执行时间:3.1336376667022705