其余排序方法:选择排序、冒泡排序、归并排序、快速排序、插入排序、希尔排序html
归并排序,顾名思义,两个有序的数组合并成一个有序的数组。只要数组的长度大于1,均可以先分为两个数组,并将这两个子数组排好序再合并。python
归并排序时稳定的排序算法,平均时间复杂度和最好最坏时间复杂度均为O(nlogn)。算法
Python代码:数组
# 归并排序 # left为归并区域的第一个下标,right为归并区域的最后一个下标 def mergeSort(arr, left, right): if left >= right: return # 中间下标 mid = left + right >> 1 # 归并当前区域的左半边区域 mergeSort(arr, left, mid) # 归并当前区域的右半边区域 mergeSort(arr, mid + 1, right) # 合并左右两边区域并排序 merge(arr, left, mid, right) # 合并左右两边区域并排序 # left为左边区域的第一个下标,mid为左边区域的最后一个下标 # mid+1为右边区域的第一个下标,right为右边区域的最后一个下标 def merge(arr, left, mid, right): # 排序须要借助一个数组 tmpArr = [] i, j = left, mid + 1 # 同时循环左右两个区域,小的数先移进tmpArr,直到其中一个区域没有数据 while i <= mid and j <= right: if arr[i] <= arr[j]: tmpArr.append(arr[i]) i += 1 else: tmpArr.append(arr[j]) j += 1 # 若左边区域还有数据,则直接添加到后面 while (i <= mid): tmpArr.append(arr[i]) i += 1 # 若右边区域还有数据,则直接添加到后面 while (j <= right): tmpArr.append(arr[j]) j += 1 # 将合并排好序的数据复制到原数组 for x in tmpArr: arr[left] = x left += 1
咱们会发现若是左右数组的数据恰好有序,那上述代码中,仍会将数据先复制到tmpArr,再复制回原数组。
只要在merge方法前加上下面的判断,就能使最好时间复杂度降为O(n):app
# 右边区域的值所有比左边区域的值大时,则不须要进行合并排序 if arr[mid] <= arr[mid + 1]: return arr
# 归并排序 # left为归并区域的第一个下标,right为归并区域的最后一个下标 def mergeSort(arr, left, right): if left >= right: return # 中间下标 mid = left + right >> 1 # 归并当前区域的左半边区域 mergeSort(arr, left, mid) # 归并当前区域的右半边区域 mergeSort(arr, mid + 1, right) # 合并左右两边区域并排序 merge(arr, left, mid, right) # 合并左右两边区域并排序 # left为左边区域的第一个下标,mid为左边区域的最后一个下标 # mid+1为右边区域的第一个下标,right为右边区域的最后一个下标 def merge(arr, left, mid, right): # 右边区域的值所有比左边区域的值大时,则不须要进行合并排序 if arr[mid] <= arr[mid + 1]: return arr # 排序须要借助一个数组 tmpArr = [] i, j = left, mid + 1 # 同时循环左右两个区域,小的数先移进tmpArr,直到其中一个区域没有数据 while i <= mid and j <= right: if arr[i] <= arr[j]: tmpArr.append(arr[i]) i += 1 else: tmpArr.append(arr[j]) j += 1 # 若左边区域还有数据,则直接添加到后面 while (i <= mid): tmpArr.append(arr[i]) i += 1 # 若右边区域还有数据,则直接添加到后面 while (j <= right): tmpArr.append(arr[j]) j += 1 # 将合并排好序的数据复制到原数组 for x in tmpArr: arr[left] = x left += 1