definsert_sort(arr): for i in range(1, len(arr)): tmp = arr[i] j = i while j and tmp < arr[j-1]: arr[j] = arr[j-1] j -= 1 arr[j] = tmp return arr
冒泡排序
将第一个记录 arr[0] 与第二个记录 arr[1] 比较,若 arr[0]>arr[1],则交换,以此类推到最后一个记录,一次冒泡的结果将数组中最大的数排到 arr 末尾。 外层 for 控制排序的执行次数,内层 for 控制一次排序中相邻记录的比较和交换,一共要执行 n 次冒泡,每次冒泡比较次数为 n-i ,因此时间复杂度 O(n2) 。相邻元素相等时没有发生交换,因此冒泡排序是稳定的。
1 2 3 4 5 6 7
defbubble_sort(arr): length = len(arr) for i in range(length): for j in range(length-i-1): if arr[j] > arr[j+1]: arr[j], arr[j+1] = arr[j+1], arr[j] #1 return arr
备注:
python 交换两个元素不需要中间变量 a,b = b,a
算法改进: 优化 1:若某一次遍历没有发生数据交换,则数组已经排好序,无需继续冒泡,设置一个 flag 来标明没有发生交换的时候
1 2 3 4 5 6 7 8 9 10 11
defbubble_sort1(arr): length = len(arr) for i in range(length): flag = 1### for j in range(length-i-1): if arr[j] > arr[j+1]: arr[j], arr[j+1] = arr[j+1], arr[j] flag = 0### if flag: break# 已排好序,直接跳出 return arr
defbubble_sort2(arr): length = len(arr) k = length-1# j的循环范围 for i in range(length): flag = 1 for j in range(k): if arr[j] > arr[j+1]: arr[j], arr[j+1] = arr[j+1], arr[j] k = j # 记录最后一次交换的位置 flag = 0 if flag: break# 已排好序,直接跳出 return arr
defquick_sort(arr, left, right): if left >= right: return low = left high = right key = arr[left] while left < right: while left < right and arr[right] >= key: #1 right -= 1 arr[left] = arr[right] while left < right and arr[left] <= key: left += 1 arr[right] = arr[left] arr[left] = key quick_sort(arr, low, left-1) quick_sort(arr, left + 1, high)
defmax_heapify(heap, heap_size, root): left = 2 * root + 1 right = 2 * root + 2 largest = root if left < heap_size and heap[largest] < heap[left]: largest = left if right < heap_size and heap[largest] < heap[right]: largest = right if largest != root: heap[largest], heap[root] = heap[root], heap[largest] max_heapify(heap, heap_size, largest)
defbuild_max_heap(heap): heap_size = len(heap) for i in range((heap_size//2)-1, -1, -1): max_heapify(heap, heap_size, i)
defheap_sort(heap): build_max_heap(heap) for i in range(len(heap)-1, -1, -1): heap[0], heap[i] = heap[i], heap[0] max_heapify(heap, i, 0) return heap
归并排序
归并排序:将两个或者两个以上的有序序列合并成一个新的有序序列。
基本思想:采用分治思想,将原始序列看做 n 个有序的子序列,然后不断合并起来。
将原始序列分为 n 个长度为 1 的子序列,并把相邻的子序列两两合并为单位为 2 的子序列。
重复上述操作,按顺序成对进行归并,直到整个序列有序。
总共进行 logn 次归并,每次归并最多比较 n 次,因此时间复杂度为 O(nlogn), 空间复杂度为 O(n) [复杂度较差]
defmerge(left, right): i, j = 0, 0 res = [] while i < len(left) and j < len(right): if left[i] <= right[j]: res.append(left[i]) i += 1 else: res.append(right[j]) j += 1 res.extend(left[i:]) res.extend(right[j:]) return res
defmerge_sort(arr): if len(arr) <= 1: return arr mid = len(arr) // 2 left = merge_sort(arr[:mid]) # 通过递归将原始序列拆为 n 个长度为 1 的子序列 right = merge_sort(arr[mid:]) return merge(left, right)
definsertionSortList(self, head): ifnot head ornot head.next: return head dummy = ListNode(0) dummy.next = head cur = head while cur.next: if cur.val > cur.next.val: pre = dummy while cur.next.val >= pre.next.val: pre = pre.next tmp = cur.next cur.next = cur.next.next tmp.next = pre.next pre.next = tmp else: cur = cur.next return dummy.next
classSolution: defsortList(self, head): ifnot head ornot head.next: return head fast = slow = head while fast.next and fast.next.next: slow = slow.next fast = fast.next.next right = self.sortList(slow.next) slow.next = None left = self.sortList(head) return self.merge(left, right) defmerge(self, left, right): dummy = ListNode(0) cur = dummy while left and right: if left.val <= right.val: cur.next = left left = left.next else: cur.next = right right = right.next cur = cur.next if left: cur.next = left if right: cur.next = right return dummy.next
classSolution(object): deffindKthLargest(self, nums, k): if k > len(nums) or k <= 0: returnNone left, right = 0, len(nums)-1 while left <= right: mid = self.quick_sort(nums, left, right) if mid == len(nums) - k: return nums[mid] elif mid < len(nums) - k: left = mid + 1 else: right = mid - 1 defquick_sort(self, nums, left, right): key = nums[left] while left < right: while left < right and nums[right] >= key: right -= 1 nums[left] = nums[right] while left < right and nums[left] <= key: left += 1 nums[right] = nums[left] nums[left] = key return left