defquickSort(nums , l , r): if l >= r : return p = partition(nums , l , r) quickSort(nums , l , p-1) quickSort(nums , p+1 , r) defpartition(nums , l , r): v = nums[l] # 表示V值所在的位置 j = l # 工作指针 i = l + 1 while i <= r: if nums[i] < v: j += 1 nums[i] , nums[j+1] = nums[j+1] , nums[i] i += 1 nums[j] , nums[l] = nums[l] , nums[j] return j
# 插入排序 definsertionSort(alist): for i inrange(1,len(alist)): currentvalue=alist[i] position=i while alist[position-1]>currentvalue and position>0: alist[position]=alist[position-1] position=position-1 alist[position]=currentvalue return alist
算法分析
时间复杂度:$O(n^2)$
空间复杂度:$O(1)$
希尔排序
算法思想
这个是插入排序的修改版,根据步长由长到短分组,进行排序,直到步长为1为止,属于插入排序的一种。
算法图解
代码实现
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
defshellSort(alist): n = len(alist) gap = n // 2 while gap > 0: for i inrange(gap): gapInsetionSort(alist, i, gap) gap = gap // 2 return alist defgapInsetionSort(alist,startpos,gap): #希尔排序的辅助函数 for i inrange(startpos+gap,len(alist),gap): position=i currentvalue=alist[i]
while position>startpos and alist[position-gap]>currentvalue: alist[position]=alist[position-gap] position=position-gap alist[position]=currentvalue
void heapify(int arr[], int n, int i) { int largest = i; // 将最大元素设置为堆顶元素 int l = 2*i + 1; // left = 2*i + 1 int r = 2*i + 2; // right = 2*i + 2 // 如果 left 比 root 大的话 if (l < n && arr[l] > arr[largest]) largest = l; // I如果 right 比 root 大的话 if (r < n && arr[r] > arr[largest]) largest = r; if (largest != i) { swap(arr[i], arr[largest]); // 递归地定义子堆 heapify(arr, n, largest); } }
void heapSort(int arr[], int n) { // 建立堆 for (int i = n / 2 - 1; i >= 0; i--) heapify(arr, n, i); // 一个个从堆顶取出元素 for (int i=n-1; i>=0; i--) { swap(arr[0], arr[i]); heapify(arr, i, 0); } }
算法分析
归并排序
二路归并排序
算法思想
归并排序是建立在归并操作上的一种有效的排序算法。该算法是采用分治法(Divide and Conquer)的一个非常典型的应用。将已有序的子序列合并,得到完全有序的序列;即先使每个子序列有序,再使子序列段间有序。若将两个有序表合并成一个有序表,称为2-路归并。
#之前copy了一份归并排序的算法,但那份代码包含太多优化行,导致算法思路不清晰 defmergeSort(arr,l,r): # l == r 时,不做任何处理,单独有序 if l < r : m = int((l + r) / 2) mergeSort(arr,l,m) mergeSort(arr , m+1 , r) merge(arr , l ,m , r)
defmerge(arr , l , m , r): copyl = arr[l:m+1] copyr = arr[m+1:r+1] lenl = len(copyl) lenr = len(copyr) i = 0 j = 0 k = l while i < lenl and j < lenr : if copyl[i] < copyr[j]: arr[k] = copyl[i] k += 1 i += 1 else: arr[k] = copyr[ j] k += 1 j += 1 while i < lenl : arr[k] = copyl[i] k += 1 i += 1 while j < lenr: arr[k] = copyr[j] k += 1 j += 1