因本人最近在恶补数据结构,学识经验有限,如有不正之处望读者指正,不胜感激;也望借此平台留下学习笔记以温故而知新。这一篇博客主要是最近刚开始接触大话数据结构一书,写的通俗易懂,很多图表帮忙理解,所以讲随手笔记分享至此,希望对您有所帮助。
排序算法的 Python 实现
# -*- coding: utf-8 -*-
"""
Created on Mon Jun 22 22:57:43 2020
@author: yx
"""
def exchange_sort(L):
'''
函数功能:简单交换排序
基本思想:内外循环,每趟循环一一比较数据并交换
参数 L:待排序数据
返回 L:完成排序的数据
'''
n = len(L)
for i in range(n-1):
for j in range(i+1, n):
if L[i] > L[j]:
L[i], L[j] = L[j], L[i]
return L
def bubble_sort(L):
'''
函数功能:冒泡排序
基本思想:内外循环,每次内循环从后向前比较,并将最大值放在末尾
参数 L:待排序数据
返回 L:完成排序的数据
'''
n = len(L)
for i in range(n):
for j in range(n-1, i, -1):
if L[i] > L[j]:
L[i], L[j] = L[j], L[i]
return L
def choose_sort(L):
'''
函数功能:简单选择排序
基本思想:内外循环,找出外循环当次一一比较后的最值索引,每轮最多交换一次
参数 L:待排序数据
返回 L:完成排序的数据
'''
n = len(L)
for i in range(n):
min = i
for j in range(i+1, n):
if L[min] > L[j]:
min = j
if i != min:
L[i], L[min] = L[min], L[i]
return L
def insert_order(L):
'''
函数功能:直接插入排序
基本思想:从第二个数开始循环,一一与外循当次数比较,小则插入其前,大则拼接其后
参数 L:待排序数据
返回 L:完成排序的数据
'''
n = len(L)
for i in range(1, n):
if L[i] < L[i-1]:
temp = L[i]
for j in range(i-1, -1, -1):
if L[j] > temp:
L[j+1] = L[j]
else:
break
L[j] = temp
return L
def shell_order(L):
'''
函数功能:希尔排序
基本思想:直接插入排序的升级,为了提升时间效率,将数据按照一定增量的子列逐步排序
参数 L:待排序数据
返回 L:完成排序的数据
'''
n = len(L)
delta = n
while(delta > 1):
delta = int(delta/3) + 1
for i in range(delta, n):
if L[i] < L[i-delta]:
temp = L[i]
for j in range(i-delta, -1, -delta):
if L[j] > temp:
L[j+delta] = L[j]
else:
break
L[j] = temp
return L
def heap_function(L, i, n):
'''
函数功能:大顶堆构建
参数 L:待排序数据
参数 i:待排序数据根结点关键字索引
参数 n:排序数据长度
返回 L:完成排序的数据
'''
temp = L[i]
s = 2*i + 1
while(s<n):
j = s
if j<(n-1) and L[j]<L[j+1]:
j += 1
if temp > L[j]:
break
L[i] = L[j]
i = j
s = 2*s + 1
L[i] = temp
return L
def heap_sort(L):
'''
函数功能:堆排序
基本思想:简单选择排序的升级,将无序列表构造大顶堆,根结点和尾结点交换,剩余数据构造大顶堆
参数 L:待排序数据
返回 L:完成排序的数据
'''
# 原始数据表构建大顶堆
n = len(L)
bi_len = int(n/2)-1
for i in range(bi_len, -1, -1):
L = heap_function(L, i, n)
# 数据交换位置,并将剩余数据构造大顶堆
for i in range(n-1, 0, -1):
L[0], L[i] = L[i], L[0]
L = heap_function(L, 0, i)
return L
def merge(L, i, m, n):
'''
函数功能:将两个有序的子列归并成一个有序列
参数 L:待排序数据
参数 i:归并开始的下标
参数 m:划分小大两部分的下标索引
参数 n:大数据两部分的最大索引
返回 L_merge:完成排序的数据
'''
L_merge = list()
j = m + 1
while(i<=m and j<=n):
if (L[i] < L[j]):
L_merge.append(L[i])
i += 1
else:
L_merge.append(L[j])
j += 1
delta_len = len(L) - len(L_merge)
if (i<=m):
for l in range(delta_len):
L_merge.append(L[i + l])
if (j<=n):
for l in range(delta_len):
L_merge.append(L[j + l])
return L_merge
def merge_function(L, s):
'''
函数功能:两两归并
参数 L:待排序数据
参数 s:归并序列长度
返回 L_merge:排序完成的序列
'''
n = len(L) - 1
k = 0
L_merge = list()
while(k<=n-2*s+1):
L_sub = L[k:k+2*s]
L_temp = merge(L_sub, 0, s-1, 2*s-1)
k = k+2*s
L_merge.extend(L_temp)
if (k<(n+1)):
for j in range(k,n+1):
L_merge.append(L[j])
return L_merge
def merge_sort(L):
'''
函数功能:归并排序
基本思想:待排数据看成某有多少数据的子序列,两两归并知道得到长度为n的有序数列
参数 L:待排序数据
返回 L_merge:完成排序的数据
'''
n = len(L)-1
k = 1
L_merge = L
while((2*k)<=n):
L_merge = merge_function(L_merge,k)
k = 2*k
if (k < (n+1)):
L_merge = merge(L_merge, 0, k-1, n)
return L_merge
def quick_function(L, low, high):
'''
函数功能:快排中划分数据集为大数据和小数据的节点
参数 L:待排序数据
参数 low:数据列表最小下标
参数 hight:数据列表最大下标
返回 low:划分节点数据
'''
# 三数取中
medium = low + int((high - low) / 2)
if (L[low] > L[high]):
L[low], L[high] = L[high], L[low]
if (L[medium] > L[high]):
L[medium], L[high] = L[high], L[medium]
if (L[medium] > L[low]):
L[medium], L[low] = L[low], L[medium]
pivot = L[low]
# 取根据划分数据的大小划分小于其数值的数据和大于其数值的数据
while(low < high):
while(low < high and L[high] >= pivot):
high -= 1
L[low], L[high] = L[high], L[low]
while(low < high and L[low] <= pivot):
low += 1
L[low], L[high] = L[high], L[low]
return low
def quick_sort(L):
'''
函数功能:快排
基本思想:冒泡排序的升级,每趟循环将待排数据划分成比当前数据小和大的两部分
参数 L:待排序数据
返回 L:完成排序的数据
'''
# 快排过程循环划分
def q_sort(L, low, high):
if (low < high):
pivot = quick_function(L, low, high)
q_sort(L, low, pivot-1)
q_sort(L, pivot+1, high)
return L
low = 0
high = len(L) - 1
L = q_sort(L, low, high)
return L
def main(L):
'''
函数功能:排序
参数 L:待排序数据
返回 L:完成排序的数据
'''
# 堆排序
heap_sort_list = heap_sort(L)
print('堆排序结果是:', heap_sort_list)
# 简单交换排序
exchange_sort_list = exchange_sort(L)
print('简单交换排序结果:', exchange_sort_list)
# 冒泡排序
bubble_sort_list = bubble_sort(L)
print('冒泡排序结果是:', bubble_sort_list)
# 简单选择排序
choose_sort_list = choose_sort(L)
print('简单选择排序结果是:',choose_sort_list)
# 直接插入排序
insert_order_list = insert_order(L)
print('直接插入排序结果是:', insert_order_list)
# 希尔排序
shell_order_list = shell_order(L)
print('希尔排序结果是:', shell_order_list)
# 归并排序
merge_sort_list = merge_sort(L)
print('归并排序结果是:', merge_sort_list)
# 快速排序
quick_sort_list = quick_sort(L)
print('快速排序结果是:', quick_sort_list)
L1 = list([9,1,5,8,3,7,4,6,2])
L2 = list([9,1,5,8,3,7,4,6,2,11])
if __name__ == "__main__":
print('---'*10 + 'L1' + '---'*10)
print('L1原始数据是:', L1)
main(L1)
print('---'*10 + 'L2' + '---'*10)
print('L2原始数据是:', L2)
main(L2)
排序结果:
------------------------------L1------------------------------
L1原始数据是: [9, 1, 5, 8, 3, 7, 4, 6, 2]
堆排序结果是: [1, 2, 3, 4, 5, 6, 7, 8, 9]
简单交换排序结果: [1, 2, 3, 4, 5, 6, 7, 8, 9]
冒泡排序结果是: [1, 2, 3, 4, 5, 6, 7, 8, 9]
简单选择排序结果是: [1, 2, 3, 4, 5, 6, 7, 8, 9]
直接插入排序结果是: [1, 2, 3, 4, 5, 6, 7, 8, 9]
希尔排序结果是: [1, 2, 3, 4, 5, 6, 7, 8, 9]
归并排序结果是: [1, 2, 3, 4, 5, 6, 7, 8, 9]
快速排序结果是: [1, 2, 3, 4, 5, 6, 7, 8, 9]
------------------------------L2------------------------------
L2原始数据是: [9, 1, 5, 8, 3, 7, 4, 6, 2, 11]
堆排序结果是: [1, 2, 3, 4, 5, 6, 7, 8, 9, 11]
简单交换排序结果: [1, 2, 3, 4, 5, 6, 7, 8, 9, 11]
冒泡排序结果是: [1, 2, 3, 4, 5, 6, 7, 8, 9, 11]
简单选择排序结果是: [1, 2, 3, 4, 5, 6, 7, 8, 9, 11]
直接插入排序结果是: [1, 2, 3, 4, 5, 6, 7, 8, 9, 11]
希尔排序结果是: [1, 2, 3, 4, 5, 6, 7, 8, 9, 11]
归并排序结果是: [1, 2, 3, 4, 5, 6, 7, 8, 9, 11]
快速排序结果是: [1, 2, 3, 4, 5, 6, 7, 8, 9, 11]