"""
============================================================
选择排序:
1、时间复杂度:O(n^2) 2、空间复杂度:O(1) 3、非稳定排序 4、原地排序
============================================================
1、找到数组中最小的那个元素,将它和数组的第一个元素交换位置(如果第一个元素就是最小元素那么它就和自己交换)
2、在剩下的元素中找到最小的元素,将它与数组的第二个元素交换位置。
3、循环往复,直到将整个数组排序。
============================================================
"""
def xuanze(a):
for i in range(len(a)):
m = i
for j in range(i, len(a)):
if a[m] > a[j]:
m = j
a[m], a[i] = a[i], a[m]
return a
"""
============================================================
插入排序:
1、时间复杂度:O(n^2) 2、空间复杂度:O(1) 3、稳定排序 4、原地排序
============================================================
1、从数组第2个元素开始抽取元素。
2、把它与左边第一个元素比较,如果左边第一个元素比它大,则继续与左边第二个元素比较下去,直到遇到不比它大的元素,然后插到这个元素的右边。
3、继续选取第3,4,....n个元素,重复步骤 2 ,选择适当的位置插入。
============================================================
"""
def charu(a):
for i in range(1, len(a)):
for j in range(i):
if a[j] > a[i]:
a.pop(i)
a.insert(j-1, a[i])
return a
"""
============================================================
希尔排序:
1、时间复杂度:O(nlogn) 2、空间复杂度:O(1) 3、非稳定排序 4、原地排序
============================================================
插入排序的变种。比较相距gap的元素并且交换
============================================================
"""
def xier(a):
n = len(a)
gap = n // 2
while gap >= 1:
for j in range(gap, n):
i = j
while (i - gap) >= 0:
if a[i] < a[i - gap]:
a[i], a[i - gap] = a[i - gap], a[i]
i -= gap
else:
break
gap //= 2
return a
"""
============================================================
冒泡排序:
1、时间复杂度:O(n^2) 2、空间复杂度:O(1) 3、稳定排序 4、原地排序
============================================================
1、把第一个元素与第二个元素比较,如果第一个比第二个大,则交换他们的位置。
2、继续比较第二个与第三个元素,如果第二个比第三个大,则交换他们的位置.
3、循环往复,直到将整个数组排序。
============================================================
优化:检测一趟遍历是否无交换,若是则直接返回结果。
============================================================
"""
def maopao(a):
for i in range(len(a)):
for j in range(len(a) - i - 1):
if a[j] > a[j + 1]:
a[j], a[j + 1] = a[j + 1], a[j]
return a
def maopao_plus(a):
for i in range(len(a)):
flag = 0
for j in range(len(a) - i - 1):
if a[j] > a[j + 1]:
a[j], a[j + 1] = a[j + 1], a[j]
flag = 1
if not flag:
break
return a
"""
============================================================
归并排序:
1、时间复杂度:O(nlogn) 2、空间复杂度:O(n) 3、稳定排序 4、非原地排序
============================================================
1、通过递归的方式将大的数组一直分割,直到数组的大小为1
2、把两个数组大小为1的合并成一个大小为2的,再把两个大小为2的合并成4的
3、循环往复,直到全部数组合并为一个数组。
============================================================
"""
def guibing(a):
if len(a) <= 1:
return a
mid = len(a) // 2
left = guibing(a[:mid])
right = guibing(a[mid:])
return merge(left, right)
def merge(left, right):
result = []
i = 0
j = 0
while i < len(left) and j < len(right):
if left[i] <= right[j]:
result.append(left[i])
i += 1
else:
result.append(right[j])
j += 1
result += left[i:]
result += right[j:]
return result
"""
============================================================
快速排序:
1、时间复杂度:O(nlogn) 2、空间复杂度:O(logn) 3、非稳定排序 4、原地排序
============================================================
1、从中轴元素那里开始把大的数组切割成两个小的数组(两个数组都不包含中轴元素)
2、通过递归的方式,让中轴元素左边的数组和右边的数组也重复同样的操作,直到数组的大小为1,此时每个元素都处于有序的位置。
============================================================
"""
def kuaisu(a,left,right):
if left >= right:
return
low = left
high = right
key = a[low]
while left < right:
while left < right and a[right] > key:
right -= 1
a[left] = a[right]
while left < right and a[left] <= key:
left += 1
a[right] = a[left]
a[right] = key
kuaisu(a, low, left - 1)
kuaisu(a, left + 1, high)
return a
"""
============================================================
堆排序:
1、时间复杂度:O(nlogn) 2、空间复杂度:O(logn) 3、非稳定排序 4、原地排序
============================================================
1、堆排序就是把堆顶的元素与最后一个元素交换
2、交换之后破坏了堆的特性,把堆中剩余的元素再次构成一个堆,然后把堆顶元素与最后第二个元素交换
3、循环往复,等到剩余的元素只有一个的时候,此时的数组就是有序的了。
============================================================
"""
def heapify(a, n, i):
largest = i
l = 2 * i + 1 # left = 2*i + 1
r = 2 * i + 2 # right = 2*i + 2
if l < n and a[i] < a[l]:
largest = l
if r < n and a[largest] < a[r]:
largest = r
if largest != i:
a[i],a[largest] = a[largest],a[i] # 交换
heapify(a, n, largest)
def dui(a):
n = len(a)
# Build a maxheap.
for i in range(n, -1, -1):
heapify(a, n, i)
# 一个个交换元素
for i in range(n-1, 0, -1):
a[i], a[0] = a[0], a[i] # 交换
heapify(a, i, 0)
return a
"""
test
逐个测试并输出排序函数结果
"""
test1 = []
test2 = [5]
test3 = [9, 2]
test4 = [2, 2]
test5 = [3, 4, 2, 74, 2, 5, 5, 6, 90, 5]
test6 = []
for i in range(100, 0, -1):
test6.append(i)
a = test5
print("选择排序",xuanze(a))
print("插入排序",charu(a))
print("希尔排序",xier(a))
print("冒泡排序",maopao(a))
print("优化冒泡",maopao_plus(a))
print("归并排序",guibing(a))
print("快速排序",kuaisu(a, 0, len(a) - 1))
print("堆排序",dui(a))