寫在前面:
參考文章:十大經典排序算法 本文的邏輯順序基於從第一篇參考博文上借鑒過來的圖,並且都是按照升序排序寫的程序,程序語言采用python。
目錄
思路:
冒泡排序的基本思想就是讓小的數逐漸‘浮上來’。也就是說:
-
第一次冒泡:將最小的數調換到最前面;
-
第二次冒泡:將第二小的數調換到最小的數的后面,也就是數組中的第二位;
-
第三次冒泡,將第三小的數調換到數組中的第三位;
... ...
代碼如下:
# 冒泡排序
def bubble_sort(nums):
# 每次冒泡,將最大的元素冒到最后面
# 第一次是前n個元素,最大的元素冒到最后
# 第二次是前n-1個元素,最大的元素冒到倒數第二個位置
# ... ...
n = len(nums)
for i in range(n-1):
for j in range(0,n-i-1):
if nums[j]>nums[j+1]:
nums[j], nums[j+1] = nums[j+1],nums[j]
return nums
時間復雜度: O(n^2),實際上是n-1 + n-2 + n-3 + ...,所以是平方的量級。
空間復雜度: O(l),沒有借助額外空間。
快速排序
思路
快速排序的基本思路就是在一遍快排中,以基准值為基礎,將比基准值小的數放到基准值的左邊,比基准值大的數放在基准值的右邊。然后在遞歸的快排基准值的左邊和右邊。至於基准值的取法,理論上來講是無所謂的。
先來一個比較簡單直接的吧。它的思路就是遍歷一遍數組,用兩個空的數組來存儲比基准值大和比基准值小的數,代碼如下:
def quick_sort1(nums):
n = len(nums)
if n ==1 or len(nums)==0:
return nums
left = []
right = []
for i in range(1,n):
if nums[i] <= nums[0]:
left.append(nums[i])
else:
right.append(nums[i])
return quick_sort1(left)+[nums[0]]+quick_sort1(right)
上面的使用了額外的空間,空間復雜度比較高,下面是基於雙指針的想法的代碼,比較常見:
def quick_sort2(nums,left,right):
l,r = left,right-1
while l < r:
if nums[r] < nums[l]:
nums[r], nums[l] = nums[l], nums[r]
l += 1
while l < r:
if nums[l] > nums[r]:
nums[r],nums[l] = nums[l], nums[r]
r -= 1
break
else:
l += 1
else:
r -= 1
if l-left > 1:
quick_sort2(nums, left, l)
if right - r > 1:
quick_sort2(nums, l+1, right)
return nums
在上面博客中看到的第三種方法,甚是巧妙,代碼如下:
def quick_sort3(nums, l, r):
if l < r:
q = partition(nums, l, r)
quick_sort(nums, l, q - 1)
quick_sort(nums, q + 1, r)
return nums
def partition(nums, l, r):
x = nums[r]
i = l - 1
for j in range(l, r):
if nums[j] <= x:
i += 1
nums[i], nums[j] = nums[j], nums[i]
nums[i + 1], nums[r] = nums[r], nums[i+1]
return i + 1
簡單插入排序
插入排序,意思是將某一個數字插入到已經排好序的數組當中。
代碼如下:
def insert_sort(nums):
n = len(nums)
for i in range(1,n):
index = i
for j in range(i-1,-1,-1):
if nums[j] > nums[index]:
nums[index],nums[j] = nums[j],nums[index]
index -= 1
else:
break
return nums
希爾排序
簡單選擇排序
簡單選擇排序,就是每一次選擇一個當前最小的元素放在已經排好序的數組的后面。
def selection_sort(nums):
n = len(nums)
for i in range(n):
index = i
for j in range(i+1,n):
if nums[j]<nums[index]:
index = j
nums[i],nums[index] = nums[index],nums[i]
return nums
堆排序
def head_sort(elems):
def siftdown(elems,e,begin,end):
i, j = begin, begin*2+1
while j < end:
if j+1 < end and elems[j+1] < elems[j]:
j += 1
if e < elems[j]:
break
elems[i] = elems[j]
i, j = j, 2*j+1
elems[i] = e
end = len(elems)
for i in range(end//2, -1, -1):
siftdown(elems, elems[i], i, end)
for i in range((end-1), 0, -1):
e = elems[i]
elems[i] = elems[0]
siftdown(elems, e, 0, i)
nums.reverse()
return nums