一、冒泡排序(交换排序)
# BubbleSort - Using bubble sort method for a chaotic sequence in ascending order, request the first to come up to the minimum. class Solution(object): def bubbleSort(self, nums): size = len(nums) for i in range(0, size - 1): j = size - 1 while j > 0: if nums[j] < nums[j - 1]: nums[j - 1], nums[j] = nums[j], nums[j - 1] j -= 1 return nums if __name__ == "__main__": s = Solution() print(s.bubbleSort(nums=[35, 80, 21, 54, 11, 45, 92, 39]))
二、选择排序
# SelectionSort - Using the selection method for a chaotic sequence in ascending order. def SelectSort(a): for i in range(0, len(a) - 1): # 外层循环 找i次最小值 min = i # 此处记录最小值位置,不能改变数列中的数值 for j in range(i + 1, len(a) - 1): # 内层循环 找到最小值 if a[j] < a[min]: min = j # 变量 j 更新并记录最小值位置 p = a[i] # 变量 p 储存最小值(把第一个最小值放入的位置的那个原有值记录在temp里) a[i] = a[min] # 将最小值覆盖到那个位置里 a[min] = p # 再把p里保存的最小值更新到未排数列的第一个 return a print(SelectSort(a=[35, 80, 21, 54, 11, 45, 92, 39]))
三、插入排序
# InsertSort - Using insertion sort method for a chaotic sequence in ascending order. class Solution(object): def insertionSort(self, nums): size = len(nums) for i in range(1, size): if nums[i] < nums[i - 1]: temp = nums[i] j = i # 记下未排序第一个的位置 while j > 0 and temp < nums[j - 1]: nums[j] = nums[j - 1] j -= 1 nums[j] = temp # 插入待排序的数字 return nums if __name__ == "__main__": s = Solution() print(s.insertionSort(nums=[35, 80, 21, 54, 11, 45, 92, 39]))
四、希尔排序——(插入排序的改进)
#!/usr/bin/env python # coding:utf-8 def shellSort(nums): # 设定步长 step = len(nums)/2 while step > 0: for i in range(step, len(nums)): # 类似插入排序, 当前值与指定步长之前的值比较, 符合条件则交换位置 while i >= step and nums[i-step] > nums[i]: nums[i], nums[i-step] = nums[i-step], nums[i] i -= step step = step/2 return nums if __name__ == '__main__': nums = [9,3,5,8,2,7,1] print shellSort(nums)
五、快速排序——(冒泡排序的改进)
过程:通过一趟排序将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另外一部分的所有数据都要小,然后再按此方法对这两部分数据分别进行快速排序(递归实现)。
一趟快速排序的算法是:
1)设置两个变量low、high,排序开始的时候:low=0,high=len(a)-1;
2)以第一个数组元素作为关键数据,赋值给key,即key=a[low];
3)从j开始向前搜索,即由后开始向前搜索(high--),找到第一个小于key的值a[high],将a[high]和a[low]互换;
4)从i开始向后搜索,即由前开始向后搜索(low++),找到第一个大于key的a[low],将a[low]和a[high]互换;
5)重复第3、4步,直到low=high;
(3,4步中,没找到符合条件的值,即3中a[high]不小于key,4中a[low]不大于key的时候改变high、low的值,使得high=high-1,low=low+1,直至找到为止。找到符合条件的值,
进行交换的时候low, high指针位置不变。另外,low==high这一过程一定正好是low+或high-完成的时候,此时令循环结束)。
# QuickSort - Using quick sort method for a chaotic sequence in ascending order. def partition(a, left, right): # 定义分区函数,第一遍排序 low = left high = right key = a[low] while low < high: while low < high and a[high] >= key: # 因为基准 key 从左开始,所以第一遍从右开始遍历 high -= 1 a[low] = a[high] while low < high and a[low] <= key: low += 1 a[high] = a[low] a[low] = key # 每一次循环结束记录一次基准 key 的位置,防止 key 值丢失 return low def QuickSort(a, left, right): # 定义递归函数 if left < right: # !!!判断条件很重要,很容易忽略 p = partition(a, left, right) QuickSort(a, left, p - 1) QuickSort(a, p + 1, right) return a a = [35, 80, 21, 54, 11, 45, 92, 39] print(QuickSort(a, 0, len(a) - 1))
六、归并排序(递归)
def merge(left,right): result=[] i,j=0,0 while i<len(left) and j<len(right): if left[i]<=right[j]: result.append(left[i]) i+=1 else: result.append(right[j]) j+=1 result+=left[i:] result+=right[j:] return result def mergesort(seq): if len(seq)<=1: return seq mid=int(len(seq)/2) left=mergesort(seq[:mid]) right=mergesort(seq[mid:]) return merge(left,right) if __name__=='__main__': seq=[4,5,7,9,7,5,1,0,7,-2,3,-99,6] print(mergesort(seq))
七、堆排序—— (选择排序的改进)
#coding: utf-8 #!/usr/bin/python import random import math #随机生成0~100之间的数值 def get_andomNumber(num): lists=[] i=0 while i<num: lists.append(random.randint(0,100)) i+=1 return lists # 调整堆 def adjust_heap(lists, i, size): lchild = 2 * i + 1 rchild = 2 * i + 2 max = i if i < size / 2: if lchild < size and lists[lchild] > lists[max]: max = lchild if rchild < size and lists[rchild] > lists[max]: max = rchild if max != i: lists[max], lists[i] = lists[i], lists[max] adjust_heap(lists, max, size) # 创建堆 def build_heap(lists, size): for i in range(0, (int(size/2)))[::-1]: adjust_heap(lists, i, size) # 堆排序 def heap_sort(lists): size = len(lists) build_heap(lists, size) for i in range(0, size)[::-1]: lists[0], lists[i] = lists[i], lists[0] adjust_heap(lists, 0, i) return lists a = get_andomNumber(10) print("排序之前:%s" %a) b = heap_sort(a) print("排序之后:%s" %b)
八、桶排序(bucket sort & bin sort)
# BucketSort - Using the Bucket Sort method for a chaotic sequence in ascending order. def BucketSort(a): b = [0] * max(a) #预先设定的列表,全部置零 result = [] for num in a: #遍历成绩,相应得分位置+1 b[num - 1] += 1 #a的值成为b的索引,此时标记b中不为空的位置 for i in range(0, len(b)): #遍历生成的列表 for j in range(0, b[i]): result.append(i + 1) return result print(BucketSort(a=[35, 80, 21, 54, 11, 45, 92, 39]))
PS:
排序算法稳定性:
假定在待排序的记录序列中,存在多个具有相同的关键字的记录,若经过排序,这些记录的相对次序保持不变,即在原序列中,ri=rj,且ri在rj之前,而在排序后的序列中,ri仍在rj之前,则称这种排序算法是稳定的;否则称为不稳定的。
稳定的排序算法:基数排序、冒泡排序、直接插入排序、折半插入排序、归并排序
不稳定的排序算法:堆排序、快速排序、希尔排序、直接选择排序
排序算法复杂度:
PS——二分查找(binary_search)
def binary_search(a, key): if not a: return 0 time = 0 low = 0 high = len(a) - 1 while low <= high: time += 1 mid = int((low + high) / 2) if a[mid] == key: print("times: %s" % time) return mid elif a[mid] > key: high = mid - 1 else: low = mid + 1 return False if __name__ == '__main__': LIST = [1, 5, 7, 8, 22, 54, 99, 123, 200, 222, 444] result = binary_search(LIST, 200) print(result)