常用的排序算法与Python实现

前言

排序算法,可以说是编程中使用最多的算法之一了,而我们了解最多的排序算法,恐怕是冒泡排序了,这个算法比较好理解,稳定,不过时间也复杂度也是O(n^2)了效果也不是很好。也有很多效果比这个好的算法,或者排序比较巧妙的算法,例如:选择排序,插入排序,快速排序,归并排序,桶排序,堆排序等等。排序算法那么多,真的突然让我去介绍一个排序算法,我还不一等能够说的出来,下面就记录几个常用的排序算法。
对于Java,Python都会有已经写好的排序算法,例如Python中的sort和sorted方法,为什么我们还要去学习这些,其实在解决一些问题的时候对数组进行排序可以解决其他问题,这就是我们要学习其思想的原因。
注:以下排序都是默认升序的。

1 选择排序

选择排序,你可以这样理解,我们先把一个数组从前往后分为两部分,第一部分就是空,第二部分就是整个数组,我们可以依次从第二个部分中拿出最小的数插到第一部分中,依此类推直至把第二部分中的元素取完。其实,这个排序方式的算法复杂度也是O(n^2),代码实现如下:

array = [7, 5, 3, 6, 44, 22, 99, 11]
def select_sort(alist):
    n = len(alist)    # 数组的长度
    for i in range(n - 1):   # 最后的那个值必然是最大的
        # 剩余列表中最小值的索引
        min_index = i
        min_num = alist[i]   # 默认第二部分中的第一个值最小
        for j in range(i + 1, n):
            if alist[min_index] > alist[j]:
                min_index = j
        # 交换
        if min_index != i:
        	alist[i], alist[min_index] = alist[min_index], alist[i]

select_sort(array)
print(array)

2 插入排序

插入排序的核心思想就是将一个列表分为两个部分,一部分是排序的,一部分没有排序,我们逐次将没有排序的元素,在已排序序列中从后往前扫描找到对应位置并插入。换句话说,就是将无序的部分插入到有序的部分中。默认数组中第一个值就是有序的,然后就剩下的部分。最好的情况就是全部有序,那么算法的时间复杂度就是O(n)了,并且该算法是稳定的。
另外:这里可以使用二分查找的方式提速。

array = [7, 5, 3, 6, 44, 22, 99, 11]

def insert_sort(alist):
    n = len(alist)
    for j in range(1, n):
        i = j
        # 无序不中的元素插入到有序的序列中
        while i > 0:
            if alist[i] < alist[i-1]:
                alist[i], alist[i-1] = alist[i-1], alist[i]
            else:
                break
            i -= 1

insert_sort(array)
print(array)

3 快速排序

快速排序就是通过一趟排序将需要排序的数据分割为独立的两部分,首先任意选取一个数据(通常选用列表的第一个数)作为基准数据,然后将所有比它小的数都放在它左边,比它大的数放在右边,到只有两个元素的时候,就自动排好序了,递归回去时就就把上一层的数据排好序了,不过算法不稳定。

array = [7, 5, 3, 6, 44, 22, 99, 11]

def quick_sort(alist, start, end):
	#递归退出条件
	if start >= end: return
	mid = alist[start]    # 默认基准数位需要排序数组的第一个数
	low, high = start, end
	while low < high:
	    # 从右向左alist[high] > mid 则high -= 1
		while low < high and alist[high] >= mid: 
			high -= 1
	    # 将high索引对应的元素赋值给low
		alist[low] = alist[high]
	    # 从左往右list[low] < mid low +=1
		while low < high and alist[low] < mid:
			low += 1
		alist[high] = alist[low]
	# 将基准数防止到对应的位置
	alist[low] = mid

	# 比基准数小的即左边的数据 要重复调用quick_sort()
	quick_sort(alist, start, low - 1)
	# 比基准数大的即右边的数据 要重复调用quick_sort()
	quick_sort(alist, low + 1, end)

quick_sort(array, 0, len(array) - 1)
print(array)

4 归并排序

归并排序也是使用递归的方法,需要辅助数组,辅助数组中存放是,当前需要合并的结果,合并的方式是:使用两个指针p1,p2,分别指向两个需要比较数组数组的开始的第一个值,然后比较这个指针指向的值,将较小的数放到辅助数组中,然后移动对应的指针进行下一次的比较,算法复杂度O(nlogn),稳定的。

array = [7, 5, 3, 6, 44, 22, 99, 11]

def merge_sort(alist):
	# 分解
	n = len(alist)
	# 递归出口
	if n <= 1:return alist
	mid = n//2
	left_list = merge_sort(alist[0: mid])
	right_list = merge_sort(alist[mid:])
	# 合并,排序结果列表
	result = []
	left_pointer, right_pointer = 0, 0 
	while left_pointer < len(left_list) and right_pointer < len(right_list):
		if left_list[left_pointer] <= right_list[right_pointer]:
			result.append(left_list[left_pointer])
			left_pointer += 1
		else:
			result.append(right_list[right_pointer])
			right_pointer += 1
	# 退出循环,将不为空的列表剩余元素添加到result中
	# result += left_list[left_pointer:]
	result.extend(left_list[left_pointer:])  # 效率更快
	# result += right_list[right_pointer:]
	result.extend(right_list[right_pointer:])
	# 返回排序后的内容
	return result

res = merge_sort(array)
print(res)

总结

排序算法较多,思想也比较独特,理解清楚这些算法后,对解决其他问题有很大的好处。
个人订阅号

常用的排序算法与Python实现

上一篇:快速排序算法__python实现


下一篇:排序与搜索(四):二分查找