一、三种比较low的排序算法
1,冒泡排序
算法思想:选出第一个数,与下一个数比较,如果后面的数更大,则互换位置,再去比较下一个数...
以此类推,使最大的数沉底,再从头开始比较,最终完成排序
代码:
def bubble_sort(li):
for i in range(len(li)-1):
for j in range(len(li)-i-1):
if li[j] > li[j+1]:
li[j], li[j+1] = li[j+1], li[j]
# 时间复杂度为O(n**2)
如果冒泡排序中执行一趟而没有交换,则列表已经是有序状态,可以直接结束算法。
def bubble_sort_1(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
if not exchange:
return
2,选择排序
算法思想:一趟遍历记录最小的数,放到第一个位置;再一趟遍历记录剩余列表中最小的数,继续放置;
直到完成排序。
代码:
def select_sort(li):
for i in range(len(li) - 1):
min_loc = i
for j in range(i+1, len(li)):
if li[j] < li[min_loc]:
min_loc = j
if min_loc != i:
li[i], li[min_loc] = li[min_loc], li[i]
# 时间复杂度为O(n**2)
3,插入排序
算法思想:列表被分为有序区和无序区两个部分。最初有序区只有一个元素。
每次从无序区选择一个元素,插入到有序区的位置,直到无序区变空。
代码:
def insert_sort(li):
for i in range(1, len(li)):
tmp = li[i]
j = i - 1
while j >= 0 and tmp < li[j]:
li[j + 1] = li[j]
j = j - 1
li[j + 1] = tmp
# 时间复杂度为O(n**2)
二、高级排序算法(时间复杂度更低,更高效)
1,快速排序法
快排算法方便快捷,既好写,执行速度又快,可以大大提高执行效率
算法思路:
1,取一个元素p(第一个元素),使元素p归位;
, 2,列表被p分成两部分,左边都比p小,右边都比p大;
3,递归完成排序。
代码:
#第一步:
def quick_sort(data, left, right):
if left < right:
mid = partition(data, left, right)
quick_sort(data, left, mid - 1)
quick_sort(data, mid + 1, right)
# 第二步:
def partition(data, left, right):
tmp = data[left]
while left < right:
while left < right and data[right] >= tmp:
right -= 1
data[left] = data[right]
while left < right and data[left] <= tmp:
left += 1
data[right] = data[left]
data[left] = tmp
return left
2,堆排序
使用二叉树完成的排序。
算法思路:
1,建立堆
2,得到堆顶元素,为最大元素
3,去掉堆顶,将堆最后一个元素放到堆顶,此时可通过一次调整重新使堆有序。
4,堆顶元素为第二大元素。
5,重复步骤3,直到堆变空。
代码:
def sift(data, low, high):
i = low
j = 2 * i + 1
tmp = data[i]
while j <= high:
if j < high and data[j] < data[j + 1]:
j += 1
if tmp < data[j]:
data[i] = data[j]
i = j
j = 2 * i + 1
else:
break
data[i] = tmp
def heap_sort(data):
n = len(data)
for i in range(n // 2 - 1, -1, -1):
sift(data, i, n - 1)
for i in range(n - 1, -1, -1):
data[0], data[i] = data[i], data[0]
sift(data, 0, i - 1)
3,归并排序
算法思路:
1,分解,把列表越分越小,直至分为一个元素。单个元素是有序的。
2,将有序的列表两两归并,列表越来越大,
代码:
def merge(li, low, mid, high):
i = low
j = mid + 1
ltmp = []
while i <= mid and j <= high:
if li[i] <= li[j]:
ltmp.append(li[i])
i += 1
else:
ltmp.append(li[j])
j += 1
while i <= mid:
ltmp.append(li[i])
i += 1
while j <= high:
ltmp.append(li[j])
j += 1
li[low:high + 1] = ltmp
def mergesort(li, low, high):
if low < high:
mid = (low + high) // 2
mergesort(li, low, mid)
mergesort(li, mid + 1, high)
merge(li, low, mid, high)
# 时间复杂度:O(nlogn)
# 空间复杂度:O(n)
4,高级排序概括
三种排序算法的时间复杂度都是O(nlogn)
一般情况下,就运行时间而言:
快速排序 < 归并排序 < 堆排序
三种排序算法的缺点:
快速排序:极端情况下排序效率低
归并排序:需要额外的内存开销
堆排序:在快的排序算法中相对较慢