十大排序算法-Python實現
一、LeetCode題目
排序數組
給你一個整數數組 nums,請你將該數組升序排列。
示例 1:
輸入:nums = [5,2,3,1]
輸出:[1,2,3,5] 示例 2:
示例 2:
輸入:nums = [5,1,1,2,0,0]
輸出:[0,0,1,1,2,5]
提示:
1 <= nums.length <= 50000
-50000 <= nums[i] <= 50000
二、十大排序算法實現
1. 冒泡排序法-優化
class Solution:
def bubble_sort(nums):
for i in range(len(nums) - 1):
flag = False # 改進後的冒泡,設置一個交換標誌位
for j in range(len(nums) - i - 1):
if nums[j] > nums[j + 1]:
nums[j], nums[j + 1] = nums[j + 1], nums[j]
flag = True
if not flag:
return nums # 這裏代表計算機偷懶成功。
2. 選擇排序
class Solution:
def selection_sort(nums):
for i in range(len(nums)):
min_idx = i
for j in range(i+1, len(nums)):
if nums[min_idx] > nums[j]:
min_idx = j
nums[i], nums[min_idx] = nums[min_idx], nums[i]
return nums
3. 插入排序
從第二個元素開始和前面的元素進行比較,如果前面的元素比當前元素大,則將前面元素 後移,當前元素依次往前,直到找到比它小或等於它的元素插入在其後面。
class Solution:
def insertion_sort(nums):
# 第一層for表示循環插入的遍數
for i in range(1, len(nums)):
for j in range(i, 0, -1):
if nums[j] < nums[j-1]:
nums[j], nums[j-1] = nums[j-1], nums[j]
else:
break
return nums
4. 快速排序
任意選取一個數據(通常選用數組的第一個數或最後一個數)作爲關鍵數據,然後將所有比它小的數都放到它前面,所有比它大的數都放到它後面,這個過程稱爲一趟快速排序。
class Solution:
def partition(arr,low,high):
i = (low-1) # 最小元素索引
pivot = arr[high]
for j in range(low,high):
# 當前元素小於或等於 pivot
if arr[j] <= pivot:
i = i+1
arr[i], arr[j] = arr[j], arr[i]
arr[i+1], arr[high] = arr[high], arr[i+1]
return i+1
def quickSort(arr,low,high):
if low < high:
pi = partition(arr, low, high)
quickSort(arr, low, pi-1)
quickSort(arr, pi+1, high)
n = len(arr)
quickSort(arr, 0, n-1)
5. 歸併排序
class Solution:
def merge_sort(arr):
if len(arr) == 1: return arr
mid = len(arr) // 2
left = arr[:mid]
right = arr[mid:]
return marge(merge_sort(left), merge_sort(right))
def marge(left, right):
res = []
while len(left) > 0 and len(right) > 0:
# 左右兩個數列第一個最小放前面
if left[0] <= right[0]:
res.append(left.pop(0))
else:
res.append(right.pop(0))
# 只有一個數列中還有值,直接添加
res += left
res += right
return res
6. 桶排序
犧牲空間
class Solution:
def bucket_sort(s):
min_num = min(s)
max_num = max(s)
# 桶的大小
bucket_range = (max_num-min_num) / len(s)
# 桶數組
count_list = [ [] for i in range(len(s) + 1)]
# 向桶數組填數
for i in s:
count_list[int((i-min_num)//bucket_range)].append(i)
s.clear()
# 回填,這裏桶內部排序直接調用了sorted
for i in count_list:
for j in sorted(i):
s.append(j)
7. 計數排序
當數值中有非整數時,計數數組的索引無法分配
class Solution:
def count_sort(s):
# 找到最大最小值
min_num = min(s)
max_num = max(s)
# 計數列表
count_list = [0]*(max_num-min_num+1)
# 計數
for i in s:
count_list[i-min_num] += 1
s.clear()
# 填回
for ind,i in enumerate(count_list):
while i != 0:
s.append(ind+min_num)
i -= 1
8. 希爾排序
減小增量排序
希爾排序,也稱遞減增量排序算法,是插入排序的一種更高效的改進版本。但希爾排序是非穩定排序算法。
希爾排序的基本思想是:先將整個待排序的記錄序列分割成爲若干子序列分別進行直接插入排序,待整個序列中的記錄"基本有序"時,再對全體記錄進行依次直接插入排序。
class solution:
def shell_sort(s):
b = len(s) #列表長度
gap = b // 2 #初始步長設置爲總長度的一半
while gap >= 1:
for i in range (b):
j = i
while j >= gap and s[j-gap] > s[j]: #在每一組裏面進行直接插入排序
s[j], s[j-gap] = s[j-gap], s[j]
j-= gap
gap = gap//2 #更新步長
9. 堆排序
class Solution:
def heapify(arr, n, i):
largest = i
l = 2 * i + 1 # left = 2*i + 1
r = 2 * i + 2 # right = 2*i + 2
if l < n and arr[i] < arr[l]:
largest = l
if r < n and arr[largest] < arr[r]:
largest = r
if largest != i:
arr[i],arr[largest] = arr[largest],arr[i] # 交換
heapify(arr, n, largest)
def heapSort(arr):
n = len(arr)
# Build a maxheap.
for i in range(n, -1, -1):
heapify(arr, n, i)
# 一個個交換元素
for i in range(n-1, 0, -1):
arr[i], arr[0] = arr[0], arr[i] # 交換
heapify(arr, i, 0)
10. 基數排序
class Solution:
def radix_sort(s):
"""基數排序"""
i = 0 # 記錄當前正在排拿一位,最低位爲1
max_num = max(s) # 最大值
j = len(str(max_num)) # 記錄最大值的位數
while i < j:
bucket_list =[[] for _ in range(10)] #初始化桶數組
for x in s:
bucket_list[int(x / (10**i)) % 10].append(x) # 找到位置放入桶數組
s.clear()
for x in bucket_list: # 放回原序列
for y in x:
s.append(y)
i += 1
注:部分排序方法,LeetCode提交代碼會超時
碼字不易,學習小白,如有不對,歡迎留言批評交流~
覺得不錯,辛苦您點個贊,觀個注~~~~~~~~
您的支持,是我不斷創作的最大動力~
歡迎點贊,關注,留言交流~
深度學習,樂此不疲~
個人微信公衆號,歡迎關注~