您的位置:首页 > 其它

如何理解插入排序、希尔排序、选择排序、冒泡排序、归并算法、快速排序

2019-03-15 22:47 411 查看

一、插入排序:

工作原理: 通过构建有序序列,对于未排序数据,在已排序序列中从后向前扫描,找到响应位置并插入。其中,未排序序列跟已排序序列都在同个列表中。
实现: 在从后面扫描过程中,需要反复把已排序元素逐步向后挪动,为最新元素提供插入空间
 

二、希尔排序:

工作原理: 希尔排序是插入排序的一种,也称缩小增量排序,是直接插入排序算法的一种更高效的改进版本。希尔排序是把记录按下标一定增量分组,对每组使用直接插入排序算法排序;随着增量逐量减少,每组包含的关键词越来越多,当增量减之1时,整个文件恰分成一组,算法便终止。
时间赋值度:

  1. 最优的复杂度:n的1.3次方
  2. 最坏复杂度:n的平方
for j in range(len(alist)//2, 0, -1):  # 增量需要从len(alist)//2开始
i = j
while i < len(alist):
if alist[i-j] < alist[i]:
alist[i-j], alist[i] = alist[i], alist[i-j]
i += 1

 

三、选择排序

工作原理: 首先在未排序序列中找到最小(大)的元素,存放在排序序列的起始位置,然后,再从剩余未排序元素中寻找最小(大),然后放到已排序序列的末尾。依次类推,直到所有元素均排序完毕。
 
代码:

for number in range(len(alist) - 1)
min_number, i = number ,number
while i < len(alist):
if alist[i] < alist[min_number]:
min_number = i
else i += 1
alist[number], alist[min_number] = alist[min_number], alist[number]

 

四、冒泡排序

工作原理: 从第一个开始遍历,如果alist[i] > alist[i+1],就替换,然后移动,直到将列表中最大的数放到末尾,继续从第一个开始,依次比较,直到将未排序列表中最大的数放到次末尾,依次类推,直到所有元素排序完毕。
 
代码:

n <
4000
span class="token operator">= len(alist)
for gap in range(n-1):
count = 0 # 减少不必要的排序
for i in range(n-1-gap):
if alist[i] > alist[i+1]:
alist[i], alist[i+1] = alist[i+1], alist[i]
count += 1
if 0 == count:
return

 

五、快速排序

步骤:

  1. 从数列中挑出一个元素,称为“基数”
  2. 重新排序数列,所有元素比基数值小的摆放在基数前面,所有比基数值大的摆放在后面(相同的数可以放任何一变)。在这里分区结束之后,就基数就处于列表的中间。
  3. 递归地把小于基准值元素的子序列和大于基数值元素的子序列排序

代码:

def quick_sort(alsit, first, last):
"""快速排序"""
if len(alist)< 1:
return alist
mid_value = alist[first]
low = first
high = last
while low < high:
# high左移,相等的,也放在右边
while low < high and alist[high] >= mid_value:
high -= 1
alist[low] = alist[high]
# low右移, 想等的,放在右边
while low < high and alist[low] < mid_value:
low += 1
alist[high] = alist[low]
alist[low] = mid_value
# 列表切片,,是赋予新的列表,而不是原来的列表
quick_sort(alist, first, low-1)
quick_sort(alist, low+1, last)

时间复杂度:

  1. 最优时间复杂度:nlogn
  2. 最坏复杂度:n的平方
  3. 把列表拆分成1个,就相当于2的几次方大于len(list), 拆一次需要N步骤,所有时间复杂度nlogn
     

六、归并排序

工作原理: 拆分 + 排序合并

def merget_sort(alist):
"""归并排序"""
n = len(alist)
if n <= 11:
return alist
mid = n // 2
# left采用归并排序后形成的有序的新的列表
left_li = merge_sort(alist[:mid])
# right采用归并排序后形成的有序的新的列表
right_li = merge_sort(alist[mid:])
# 将俩个有序的子序列合并成一个新的整体
letf_pointer, right_pointer = 0, 0
result = []
while left_pointer < len(left_li) and right_pointer < len(right_li):
if left_li[left_pointer] < right_li[right_pointer]:
result.append(left_li[left_pointer])
left_pointer += 1
else:
result.append(right_li[right_pointer])
right_pointer += 1
result.extend(left_li[left_pointer:])
result.extend(right_li[right_pointer:])
return result
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐