您的位置:首页 > 编程语言 > Python开发

八种基础排序(简单选择排序/堆排序/直接插入排序/希尔排序/快速排序/冒泡排序/归并排序/基数排序)-- python实现

2019-04-11 00:48 495 查看

python2.7

默认增序排列

思路写在每种排序的代码上的注释~

输入sort选择排序算法

输入排序名选择排序,名称如下

[code]switch = {
"简单选择排序":1,
"堆排序":2,
"直接插入排序":3,
"希尔排序":4,
"快速排序":5,
"冒泡排序":6,
"归并排序":7,
"基数排序":8
}

默认排序列表:

[code]lst = [123, 234, 564, 765, 876, 324, 651, 874, 432]

代码展示:

[code]# coding=utf-8
import math
from random import shuffle

# 两层循环
# 第一层从列表开始到结尾标识已排序元素与未排序元素
# 第二层从未排序元素中找到最小值的下标
# 将最小值交换至以排序列表尾
# 时间复杂度O(n^2)
# 不稳定
def sort1(lst):
# 简单选择排序
l = len(lst)
for i in range(l-1):
min = i
for j in range(i, l):
if lst[j] < lst[min]:
min = j
tmp = lst[i]
lst[i] = lst[min]
lst[min] = tmp

# 这个是堆排序
# 现在12点了
# 我明天写完放进来
def sort2(lst):
# 堆排序
l = len(lst)

# 两层循环
# 第一层循环分离已排序元素与未排序元素
# 第二层循环将列表第一个未排序元素插入至已排序元素的正确位置
# 时间复杂度O(n^2)
# 稳定排序
def sort3(lst):
# 直接插入排序
l = len(lst)
for i in range(1, l):
tmp = lst[i]
for j in range(i-1, -1, -1):
if lst[j] > tmp:
lst[j+1] = lst[j]
lst[j] = tmp
else:
break

# 希尔排序又名缩小增量排序
# 希尔排序首先需要一个增量序列,此处增量选择gap=length/2,缩小增量方式:gap = gap/2
# 设增量序列为gap_list,在排序中,按照增量序列的顺序,依次将待排序列表分为gap个子序列
# 依次对子序列进行直接插入排序,取gap_list下一个增量,重复子序列排序操作,直至增量为1
# 希尔排序容易实现且代码简短,最坏与平均效率相差不大
# 希尔排序的效率极大取决于增量序列的选择,对于中等数据规模建议用希尔排序
# 对于较大数据规模,若实际情况不适用可更改为快排
# 时间复杂度O(n^1.3) - O(n^2)
# 不稳定
def sort4(lst):
# 希尔排序
l = len(lst) / 2
gap_list = []
while l > 0:
gap_list.append(l)
l = l // 2
print gap_list
for gap in gap_list:
print "增量为%d的排序" % gap,lst
for i in range(gap):
for j in range(i+gap, len(lst), gap):
tmp = lst[j]
for k in range(j-gap, -1, -gap):
if lst[k] > tmp:
lst[k+gap] = lst[k]
lst[k] = tmp
else:
break

# 快速排序,递归实现
# 1.任意选择一个元素作为轴(一般为数组第一个)
# 2.将比轴大的放右边,比轴小的放左边
# 3.对轴左右序列,递归函数实现步骤1、2至序列元素为1
# 平均时间复杂度O(nlogn)
# 最差情况O(n^2):每次取到的都是数组最大或最小值
# 不稳定
def sort5(lst, low, high):
i = low
j = high
if i >= j:
return lst
mid = lst[i]
while i != j:
while i < j and lst[j] >= mid:
j = j - 1
lst[i] = lst[j]
while i < j and lst[i] <= mid:
i = i + 1
lst[j] = lst[i]
lst[i] = mid
sort5(lst, low, i-1)
sort5(lst, j+1, high)

# 两层循环
# 第一层标识待排序数列
# 第二层从头向尾将待排序中最大值推移至待排序数列尾
# 时间复杂度O(n^2)
# 稳定
def sort6(lst):
# 冒泡排序
l = len(lst)
for i in range(l-1, 0, -1):
for j in range(i):
if lst[j] > lst[j+1]:
tmp = lst[j]
lst[j] = lst[j+1]
lst[j+1] = tmp

# 归并排序,先递归再排序
# 分而治之
# 核心在于merge函数,将两个以排序完成数列合并
# 先递归至元素为1,再通过merge函数向上合并
# 时间复杂度O(nlogn)
# 空间复杂度O(n)
# 稳定
def sort7(lst):
if len(lst) <= 1:
return lst
mid = len(lst) // 2
left = sort7(lst[:mid])
right = sort7(lst[mid:])
return merge(left, right)

def merge(left, right):
r, l = 0, 0
result = []
while l < len(left) and r < len(right):
if left[l] < right[r]:
result.append(left[l])
l = l + 1
else:
result.append(right[r])
r = r + 1
result += left[l:]
result += right[r:]
print result
return result

# 基数排序属于分配式排序
# 1.取数列最大值的位数作为基础
# 2.此代码默认堆数为10
# 3.按照个位数大小将待排序数列放入对应堆,完成此操作后依次合并数组
# 4.按找个位、十位、百位直至最高位的大小重复步骤3
# 时间复杂度为O (nlog(r)m),其中r为所采取的基数,而m为堆数
def sort8(lst):
# 桶排序/基数排序
radix = 10
k = int(math.ceil(math.log(max(lst), 10)))
bucket = [[] for i in range(radix)]
for i in range(k):
for value in lst:
bucket[value//(10 ** i) % 10].append(value)
del lst[:]
for arr in bucket:
lst.extend(arr)
print lst
bucket = [[] for i in range(radix)]

switch = {
"简单选择排序":1,
"堆排序":2,
"直接插入排序":3,
"希尔排序":4,
"快速排序":5,
"冒泡排序":6,
"归并排序":7,
"基数排序":8
}

if __name__ == '__main__':
while raw_input("输入sort选择排序算法") == "sort":
sort_name = raw_input("请输入需要的排序算法:")
flag = switch[sort_name]
lst = [123, 234, 564, 765, 876, 324, 651, 874, 432]
if flag == 1:
sort1(lst)
print "简单选择排序:", lst
shuffle(lst)
print lst
elif flag == 3:
sort3(lst)
print "直接插入排序:", lst
shuffle(lst)
print lst
elif flag == 4:
sort4(lst)
print "希尔排序:", lst
shuffle(lst)
print lst
elif flag == 5:
sort5(lst, 0, len(lst)-1)
print "快速排序:", lst
shuffle(lst)
print lst
elif flag == 6:
sort6(lst)
print "冒泡排序:", lst
shuffle(lst)
print lst
elif flag == 7:
print "归并排序:", sort7(lst)
shuffle(lst)
print lst
elif flag == 8:
sort8(lst)
print "基数排序:", lst
shuffle(lst)
print lst

 

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: