概述:
整理了一下自己学习数据结构与算法过程中利用python实现的常见排序算法,包括:冒泡排序,插入排序,选择排序,归并排序,快速排序,堆排序,计数排序。下面依次贴出代码。
一.复杂度为O(n^2)的算法
1.冒泡排序
def bubbleSort(seq):
"冒泡排序"
n = len(seq)
print("待排序列表")
print(seq)
for i in range(n - 1):
for j in range(n - 1 - i):
if seq[j] > seq[j + 1]:
seq[j], seq[j + 1] = seq[j + 1], seq[j]
print("冒泡排序后列表")
print(seq)
return seq
2.插入排序
def insertSort(seq):
"插入排序"
n = len(seq)
print("待排序列表")
print(seq)
for i in range(1, n):
value = seq[i]
pos = i
while pos > 0 and value < seq[pos - 1]:
seq[pos] = seq[pos - 1]
pos -= 1
seq[pos] = value
print("排序后列表")
print(seq)
return seq
3.选择排序
def selectSort(seq):
"选择排序"
n = len(seq)
print("待排序列表")
print(seq)
for i in range(n):
min_idx = i
for j in range(i + 1, n):
if seq[j] < seq[min_idx]:
min_idx = j
if min_idx != i:
seq[i], seq[min_idx] = seq[min_idx], seq[i]
print("排序后列表")
print(seq)
return seq
二.复杂度为O(n * logn)的算法
1.归并排序
def mergeSort(seq, l, r):
"归并排序"
if r == l:
return seq
mid = int((r - l) / 2) + l
mergeSort(seq, l, mid)
mergeSort(seq, mid + 1, r)
merge(seq, l, mid, r)
def merge(seq, l, mid, r):
a, b = l, mid + 1
new_sorted_seq = list()
while a <= mid and b <= r:
if seq[a] <= seq[b]:
new_sorted_seq.append(seq[a])
a += 1
else:
new_sorted_seq.append(seq[b])
b += 1
while a <= mid:
new_sorted_seq.append(seq[a])
a += 1
while b <= r:
new_sorted_seq.append(seq[b])
b += 1
for i in range(0, len(new_sorted_seq)):
seq[l + i] = new_sorted_seq[i]
2.随机快速排序
import random
def partition(seq, l, r):
change_index = random.randint(l, r)
seq[change_index], seq[r] = seq[r], seq[change_index]
num = seq[r]
less_index = l - 1
more_index = r + 1
p = l
while more_index > p:
if seq[p] < num:
less_index += 1
seq[p], seq[less_index] = seq[less_index], seq[p]
p += 1
elif seq[p] == num:
p += 1
else:
more_index -= 1
seq[p], seq[more_index] = seq[more_index], seq[p]
p = [less_index + 1, more_index - 1]
return p
def quickSort(seq, l, r):
if r - l < 1:
return seq
else:
p = partition(seq, l, r)
quickSort(seq, l, p[0] - 1)
quickSort(seq, p[1] + 1, r)
三.其它排序算法
1.堆排序
这块代码和堆实现放在一起了,里面有一个用O(n)复杂度将列表变成一个堆的实现方法quickHeapify
def heapInsert(list, index):
#index位置上的数是新加的,
# 0~index - 1上已经是大根堆了,该函数实现0~index上重整为大根堆
"向上寻找位置"
while list[index] > list[int((index - 1) / 2)]:
list[index], list[int((index - 1) / 2)] = list[int((index - 1) / 2)],
list[index]
index = int((index - 1) / 2)
def heapify(list, index, size):
"list[index]上的数变小了,向下调整"
l = index * 2 + 1
#判断是否有左儿子
while l < size:
#判断是否存在右儿子,如果不存在,最大为左儿子
r = l + 1
if r >= size:
large = l
else:
if list[l] >= list[r]:
large = l
else:
large = r
if list[index] >= list[large]:
break
list[index], list[large] = list[large], list[index]
index = large
l = index * 2 + 1
def quickHeapify(list):
"用O(n)的时间复杂度将数组变为一个大根堆"
size = len(list)
k = int(math.log(size, 2))
index = 2 ** k - 2
for i in range(0, index + 1):
heapify(list, index - i, size)
def heapSort(list):
"堆排序"
#首先将列表变成一个大根堆
print("待排序列表:", list)
n = len(list)
quickHeapify(list)
print("大根堆列表:", list)
for i in range(0, n - 1):
list[0], list[n - 1 - i], = list[n - 1 - i], list[0]
heapify(list, 0, n - 1 - i)##
print("排序后列表:", list)
return list
2.计数排序
计数排序是桶排序的一种,复杂的为O(n)但是是基于数据类型的一种排序,我实现的是对[m,n]范围内的整数列表排序的方法
import numpy as np
#计数排序
def countingSort(seq, min, max):
"计数排序,输入的seq范围在min~max间"
couter = list(range(min, max + 1))
n = len(seq)
for i in range(0, n):
couter[seq[i] - min] += 1
newseq = []
for j in range(0, max - min + 1):
newseq += couter[j] * [j + min]
print(newseq)
return newseq
a = np.random.randint(3, 6, size = 10)
mina = min(a)
maxa = max(a)
b = countingSort(a, mina, maxa)