学编程不可避免都会接触算法,虽然python已经内置了相应的函数,但了解一下算法的原理还是很有必要的。
本文主要介绍排序算法的思想和python实现:
1、冒泡排序
算法描述:
重复地访问要排序的列表,一次比较两个元素,如果他们的顺序错误就把他们交换过来。访问列表的工作是重复地进行直到没有再需要交换,也就是说该数列已经排序完成。
1 def bubble(bubbleList): 2 listLength = len(bubbleList) 3 while listLength > 0: 4 for i in range(listLength - 1): 5 if bubbleList[i] > bubbleList[i + 1]: 6 bubbleList[i],bubbleList[i+1] = bubbleList[i+1],bubbleList[i] 7 listLength -= 1 8 print bubbleList 9 10 11 if __name__ == '__main__': 12 bubbleList = [3, 4, 1, 2, 5, 8, 0,34,45,23,12,56,67,21] 13 bubble(bubbleList)
2、快速排序
算法描述:
1.先从数列中取出一个数作为基准数。
2.分区过程,将比这个数大的数全放到它的右边,小于或等于它的数全放到它的左边。
3.再对左右区间重复第二步,直到各区间只有一个数。
1 def quickSort(L, low, high): 2 i = low 3 j = high 4 if i >= j: 5 return L 6 key = L[i] 7 while i < j: 8 while i < j and L[j] >= key: #从数组的右端开始向前找,一直找到比key小的数字为止 9 j = j-1 10 L[i] = L[j] #最终找到了比key小的元素,要做的事情就是此元素放到i的位置 11 12 while i < j and L[i] <= key: #从数组的左端开始向后找,一直找到比key大的数字为止 13 i = i+1 14 L[j] = L[i] #最终找到了比key大的元素,要做的事情就是将此元素放到j的位置 15 16 L[i] = key #最后就是把key放到i的位置 17 18 #递归查询 19 quickSort(L, low, i-1) 20 quickSort(L, j+1, high) 21 22 return L 23 24 if __name__ == '__main__': 25 array = [8,10,9,6,4,16,5,13,26,18,2,45,34,23,1,7,3] 26 sortlist = quickSort(array,0,len(array)-1) 27 print sortlist
3、堆排序
算法描述:
堆排序(Heapsort)是指利用堆积树(堆)这种数据结构所设计的一种排序算法,它是选择排序的一种。
可以利用数组的特点快速定位指定索引的元素。堆分为大根堆和小根堆,是完全二叉树。
大根堆的要求是每个节点的值都不大于其父节点的值,即A[PARENT[i]] >= A[i]。在数组的非降序排序中,需要使用的就是大根堆,因为根据大根堆的要求可知,最大的值一定在堆顶。
1 def fixDown(a, k, n): # 自顶向下堆化,从k开始堆化 2 N = n - 1 3 while 2 * k <= N: 4 j = 2 * k 5 if j < N and a[j] < a[j + 1]: # 选出左右孩子节点中更大的那个 6 j += 1 7 if a[k] < a[j]: #孩子节点最大的和父节点进行比较,将值大的放在父节点 8 a[k], a[j] = a[j], a[k] 9 k = j 10 else: 11 break 12 13 14 def heapSort(l): 15 n = len(l) - 1 16 for i in range(n // 2, 0, -1): 17 fixDown(l, i, len(l)) 18 while n > 1: 19 l[1], l[n] = l[n], l[1] 20 fixDown(l, 1, n) 21 n -= 1 22 return l[1:] 23 24 25 l=[-1,26,5,77,1,61,11,59,15,48,19] #第一个元素不用,占位 26 res = heapSort(l) 27 print(res)
4、直接选择排序
基本思想:
第1趟,在待排序记录r1 ~ r[n]中选出最小的记录,将它与r1交换;
第2趟,在待排序记录r2 ~ r[n]中选出最小的记录,将它与r2交换;
以此类推,第i趟在待排序记录r[i] ~ r[n]中选出最小的记录,将它与r[i]交换,使有序序列不断增长直到全部排序完毕。
1 def select_sort(lists): 2 count = len(lists) 3 for i in range(0, count): 4 min = i 5 for j in range(i + 1, count): 6 if lists[min] > lists[j]: 7 min = j 8 lists[min], lists[i] = lists[i], lists[min] 9 return lists 10 11 12 if __name__ == '__main__': 13 array = [8,10,9,6,4,16,5,13,26,18,2,45,34,23,1,7,3] 14 sort_array = select_sort(array) 15 print sort_array
5、直接插入排序
算法描述:
插入排序的基本操作就是将一个数据插入到已经排好序的有序数据中,从而得到一个新的、个数加一的有序数据,
算法适用于少量数据的排序,时间复杂度为O(n^2)。是稳定的排序方法。
插入算法把要排序的数组分成两部分:
第一部分包含了这个数组的所有元素,但将最后一个元素除外(让数组多一个空间才有插入的位置),
而第二部分就只包含这一个元素(即待插入元素)。
在第一部分排序完成后,再将这个最后元素插入到已排好序的第一部分中。
1 def insert_sort(lists): 2 count = len(lists) #列表长度 3 for i in range(1, count): 4 key = lists[i] #保存要进行插入排序的数字 5 j = i - 1 6 #让key和已排列好的列表逐一进行比较,将key放在合适的位置 7 while j >= 0: 8 if lists[j] > key: 9 lists[j + 1] = lists[j] 10 lists[j] = key 11 j -= 1 12 return lists 13 14 15 if __name__ == '__main__': 16 nums = [10,8,4,-1,2,6,7,3] 17 print 'nums is:', nums 18 insert_sort(nums) 19 print 'insert sort:', nums
6、希尔排序
算法描述:
希尔排序(Shell Sort)是插入排序的一种。也称缩小增量排序,是直接插入排序算法的一种更高效的改进版本。
希尔排序是非稳定排序算法。
希尔排序是把记录按下标的一定增量分组,对每组使用直接插入排序算法排序;
随着增量逐渐减少,每组包含的关键词越来越多,当增量减至1时,整个文件恰被分成一组,算法便终止。
1 def shell_sort(lists): 2 count = len(lists) 3 step = 2 4 group = count / step 5 while group > 0: 6 for i in range(0, group): 7 j = i + group 8 while j < count: 9 k = j - group 10 key = lists[j] 11 while k >= 0: 12 if lists[k] > key: 13 lists[k + group] = lists[k] 14 lists[k] = key 15 k -= group 16 j += group 17 group /= step 18 return lists 19 20 21 if __name__ == '__main__': 22 nums = [10,8,4,-1,2,6,7,3] 23 print 'nums is:', nums 24 shell_sort(nums) 25 print 'shell sort:', nums
参考资料:
算法系列15天速成
八大排序算法的 Python 实现