插入排序(lnsertion Sort)
插入排序是⼀种简单直观的排序算法。它的⼯作原
理是通过构建有序序列,对于未排序数据,在已排序序列中从后向前扫描,找到相应位置并插⼊。插⼊排序在实现上,在从后向前扫描过程中,需要反
复把已排序元素逐步向后挪位,为最新元素提供插⼊空间。
代码实现:
def insert_sort(alist):
"""插入排序"""
for j in range(1, len(alist)):
for i in range(j, 0, -1):
if alist[i] < alist[i - 1]:
alist[i - 1], alist[i] = alist[i], alist[i - 1]
else:
break
if __name__ == '__main__':
list1 = [8, 4, 6, 5, 7, 9, 2, 3, 1]
insert_sort(list1)
print(list1)
时间复杂度
- 最优时间复杂度:O(n) (升序排列,序列已经处于升序状态)
- 最坏时间复杂度:O(n²)
- 稳定性:稳定
希尔排序(shell sort)
希尔排序是插入排序的一种。也称缩小增量排序,是直接插入排序算法的一种更高效的改进版本。希尔排序是⾮稳定排序算法。该⽅法因 DL.Shell于1959年提出⽽得名。希尔排序是把记录按下标的⼀定增量分
组,对每组使⽤直接插⼊排序算法排序;随着增量逐渐减少,每组包含的关 键词越来越多,当增量减⾄1时,整个⽂件恰被分成⼀组,算法便终⽌。
希尔排序过程
希尔排序的基本思想是:将数组列在⼀个表中并对列分别进⾏插⼊排序,重复这过程,不过每次⽤更⻓的列(步⻓更⻓了,列数更少了)来进⾏。最后整个表就只有⼀列了。将数组转换⾄表是为了更好地理解这算法,算法本身 还是使⽤数组进⾏排序。
代码实现:
def shell_sort(alist):
"""希尔排序"""
n = len(alist)
gap = n // 2
while gap >= 1:
for j in range(gap, n):
i = j
while (i - gap) >= 0:
if alist[i] < alist[i - gap]:
alist[i], alist[i - gap] = alist[i - gap], alist[i]
else:
break
gap //= 2
if __name__ == '__main__':
list1 = [5, 7, 6, 8, 2, 9, 1, 3, 4]
shell_sort(list1)
print(list1)
时间复杂度
- 最优时间复杂度:根据步⻓序列的不同⽽不同
- 最坏时间复杂度:O(n )
- 稳定性:不稳定
快速排序(Quicksort)
快速排序(英语:Quicksort),⼜称划分交换排序(partition-exchange
sort),通过⼀趟排序将要排序的数据分割成独⽴的两部分,其中⼀部分的 所有数据都⽐另外⼀部分的所有数据都要⼩,然后再按此⽅法对这两部分数
据分别进⾏快速排序,整个排序过程可以递归进⾏,以此达到整个数据变成 有序序列。
代码实现:
def quick_sort(alist, start, end):
"""快速排序"""
if start >= end:
return
mid = alist[start]
left = start
right = end
while left < right:
while left < right and alist[right] >= mid:
right -= 1
alist[left] = alist[right]
while left < right and alist[left] < mid:
left += 1
alist[right] = alist[left]
alist[left] = mid
quick_sort(alist, start, left-1)
quick_sort(alist, left+1, end)
if __name__ == '__main__':
list1 = [5, 7, 6, 8, 2, 9, 1, 3, 4]
quick_sort(list1, 0, len(list1)-1)
print(list1)
时间复杂度
- 最优时间复杂度:O(nlogn)
- 最坏时间复杂度:O(n²)
- 稳定性:不稳定
归并排序
归并排序是采⽤分治法的⼀个⾮常典型的应⽤。归并排序的思想就是先递归 分解数组,再合并数组。
将数组分解最⼩之后,然后合并两个有序数组,基本思路是⽐较两个数组的 最前⾯的数,谁⼩就先取谁,取了后相应的指针就往后移⼀位。然后再⽐
较,直⾄⼀个数组为空,最后把另⼀个数组的剩余部分复制过来即可。
代码实现
def merge_sore(alist):
"""归并排序"""
n = len(alist)
if 1 == n:
return alist
mid = n // 2
# 对左半部分进行归并排序
left_sorted_li = merge_sore(alist[:mid])
# 对右半部分进行归并排序
right_sorted_li = merge_sore(alist[mid:])
# 合并两个有序集合
left, right = 0, 0
merge_sorted_li = []
left_n = len(left_sorted_li)
right_n = len(right_sorted_li)
while left < left_n and right < right_n:
if left_sorted_li[left] <= right_sorted_li[right]:
merge_sorted_li.append(left_sorted_li[left])
left += 1
else:
merge_sorted_li.append(right_sorted_li[right])
right += 1
merge_sorted_li += left_sorted_li[left:]
merge_sorted_li += right_sorted_li[right:]
return merge_sorted_li
if __name__ == '__main__':
list1 = [5, 7, 6, 8, 2, 9, 1, 3, 4]
a = merge_sore(list1)
print(a)
时间复杂度
- 最优时间复杂度:O(nlogn)
- 最坏时间复杂度:O(nlogn)
- 稳定性:稳定
exit(?)