常见排序算法总结
时间空间复杂度(大O表示法)
时间复杂度
1.常数阶O(1):无论代码执行了多少行,只要是没有循环等复杂结构,那这个代码的时间复杂度都是O(1)
2.线性阶O(n):for循环里的代码会执行n遍,因此消耗的时间是随着n的变化而变化
3.对数阶O(logN):若在一个while循环中,每次都将i乘以2,乘完之后,i距离n就越来越近。假设循环x次,循环退出。即,2的x次方等于n,那么x=log2^n
4.线性对数阶O(nlogN):将时间复杂度为O(logN)的代码循环n次
5.平方阶O(n^2):将时间复杂度为O(n)的代码再嵌套循环一遍
空间复杂度
1.O(1):如果算法执行所需要的临时空间不随着某个变量n的大小而变化
2.O(n):如果第一行new了个新数组,占用大小为n,此后代码没有再分配新的空间,则这段代码的空间复杂度为O(n)
常见的排序算法
排序算法 | 最坏时间复杂度 | 平均时间复杂度 | 空间复杂度 | 稳定性 |
冒泡 | O(n^2) | O(n^2) | O(1) | 稳定 |
直接插入 | O(n^2) | O(n^2) | O(1) | 稳定 |
直接选择 | O(n^2) | O(n^2) | O(1) | 不稳定 |
快速 | O(n^2) | O(nlogn) | O(n) | 不稳定 |
堆排 | O(nlogn) | O(nlogn) | O(1) | 不稳定 |
归并 | O(nlogn) | O(nlogn) | O(n) | 稳定 |
基数 | O(d(n+r)) | O(d(n+r)) | O(rd+n) | 稳定 |
冒泡排序
参考:leetcode,912排序数组,此题用冒泡排序不满足时间复杂度
1 def maopao(nums): 2 for i in range(len(nums)-1): 3 for j in range(len(nums)-i-1): 4 if nums[j] > nums[j+1] 5 nums[j],nums[j+1] = nums[j+1],nums[j] 6 return nums 7 8 if __name__== '__main__': 9 input = [5,2,3,1] 10 output = maopao(input) 11 print(output)
插入排序
此题用插入排序依然不满足时间复杂度
1 def InsertSort(nums): 2 for i in range(1,len(nums)): 3 preindex = i - 1 4 current = nums[i] 5 while (preindex>=0 and nums[preindex] > current): 6 nums[preindex + 1] = nums[preindex] 7 preindex -= 1 8 nums[preindex+1] = current 9 return nums 10 if __name__ == '__main__': 11 input = [5,2,3,1] 12 output = InsertSort(input) 13 print(output)
选择排序
每一次从待排序的数据元素中选择最小(或者最大)的一个元素,存放在序列的起始位置。然后再从剩余未排序元素中继续寻找最小(或者最大)的元素,然后放到已排序序列的末尾。
def Selete(nums): for i in range(0, len(nums)-1): max_index = i for j in range(i+1, len(nums)): if nums[max_index] > nums[j]: max_index = j nums[i],nums[max_index] = nums[max_index],nums[i] return nums if __name__ == '__main__': input = [5,2,3,1] output = Selete(input) print(output)
快速排序
1 def QuickSort(nums,left,right): 2 if left < right: 3 i = left 4 j =right 5 #令第一个数为baseline 6 baseline = nums[left] 7 while i != j: 8 #交替扫描和交换 9 #从右向左找到第一个比baseline小的值,交换 10 while j > i and nums[j] > baseline: 11 j -= 1 12 if j > i: 13 nums[i] = nums[j] 14 i += 1 15 #从左向右找到第一个比baseline大的值,交换 16 while i < j and nums[i] < baseline: 17 i +=1 18 if i < j: 19 nums[j] = nums[i] 20 j -= 1 21 #至此,完成了一次快排 22 nums[i] = baseline 23 #以i为baseline进行子序列元素交换 24 QuickSort(nums, left, i-1) 25 QuickSort(nums, i+1, right) 26 return nums 27 if __name__ == '__main__': 28 input = [5,2,3,1] 29 output = QuickSort(input, 0, len(input) - 1) 30 print(output)
未完待续
参考: