介绍:
def bubbleSort(nums): n = len(nums) for i in range(1,n): #设置循环次数 for j in range(n-i): # 每次循环都会确定一次最大值,所以下一次比较就不用再对后i个数比较了 if nums[j]>nums[j+1]: #和选择排序的区别 nums[j], nums[j+1] = nums[j+1], nums[j] return nums # 优化:某一趟遍历如果没有数据交换,说明已经排好序了,因此不用再迭代了,用一个标记记录这个状态 def betterBubbleSort(nums): n = len(nums) flag = True for i in range(1,n): #设置循环次数 if flag == False: break flag = False for j in range(n-i): # 每次循环都会确定一次最大值,所以下一次比较就不用再对后i个数比较了 if nums[j]>nums[j+1]: #和选择排序的区别 nums[j], nums[j+1] = nums[j+1], nums[j] flag = True return nums
def selectSort(nums): n = len(nums) for i in range(n): for j in range(i+1,n): #开始一趟比较,从i+1到数组的末尾,找出最小值 if nums[i] > nums[j]: nums[i], nums[j] = nums[j], nums[i] return nums
def insertSort(nums): n = len(nums) for i in range(1, n): temp = nums[i] # 第一个元素认为已经排序了,所以从第二个开始 index =i for j in range(i-1, -1, -1): if nums[j] > temp: nums[j+1] = nums[j] # 将所以在nums[i]之前的大于nums[i]的都后移一位 index = j # 用index记录指针的变化 else: break nums[index] = temp # 移动完所以大于nums[i]的值后,index刚好指向最靠前一个大于nums[i]的位置 return nums
def QSort(nums, low, high): pivot = nums[low] # 取第一个元素为基准值 #low < high 是安全判断,防止数组越界,只要进行了指针加减都要判断 while low < high: while low < high and nums[high] >= pivot: high -= 1 if low < high: nums[low], nums[high] = nums[high], nums[low] low += 1 while low < high and nums[low] <= pivot: low += 1 if low < high: nums[low], nums[high] = nums[high], nums[low] high -= 1 return low def quickSort(nums, low, high): if low < high: mid = QSort(nums, low, high) quickSort(nums, low, mid-1) quickSort(nums, mid+1, high) return nums
归并排序是采用分治法的一个非常典型的应用。
def merge(nums, low, mid, high): l = low # 第一段序列下标 m = mid+1 # 第二段序列下标 h = 0 # 新序列序列下标 b = [0]*(high+1) # 新序列 while l <= mid and m <= high: # 把两个子序列的头元素比较,取较小者进入新序列,然后在久序列中指针+1,开始下一次比较 if nums[l] <= nums[m]: b[h] = nums[l] h += 1 l += 1 else: b[h] = nums[m] h += 1 m += 1 while l <= mid: # 若第一段序列没有扫描完,将其全部赋值到合并序列中 b[h] = nums[l] h += 1 l += 1 while m <= high: # 若第二段序列没有扫描完,将其全部赋值到合并序列中 b[h] = nums[m] h += 1 m += 1 for i in range(h): # 将分段排序得到的新数组复制到之前的数组 nums[low+i] = b[i] def mergeSort(nums, low, high): if low < high: mid = int((low+high)/2) mergeSort(nums, low, mid) # 分解 mergeSort(nums, mid+1, high) merge(nums, low, mid, high) # 合并 return nums #--------------------------------------------------------------- #python的方法 def merge_sort(nums): if len(nums) <= 1: return nums mid = int(len(nums)/2) # 二分分解 left = merge_sort(nums[:mid]) right = merge_sort(nums[mid:]) return merge_(left,right) # 合并数组 def merge_(left, right): l, r = 0, 0 #定义left和right下标 result = [] while l<len(left) and r<len(right): if left[l] < right[r]: result.append(left[l]) l += 1 else: result.append(right[r]) r += 1 # 将剩余数组直接加到结果数组中 result += left[l:] result += right[r:] return result
def heapSort(nums): n = len(nums) first = int(n/2 -1) # 最后一个非叶子节点 #构建最大堆 for start in range(first, -1, -1): percDown(nums, start, n-1) #循环,每次把根节点和最后一个节点调换位置 for end in range(n-1, 0, -1): nums[0], nums[end] = nums[end], nums[0] #根节点是最大值,所以直接放在最后 percDown(nums, 0, end-1) # end-1 最后一位已经是最大的了,不用加入判断了 return nums #最大堆调整:将堆的末端子节点做调整,使得子节点永远小于父节点 #start为当前需要调整最大堆的位置,end为调整边界 def percDown(nums, start, end): root = start while True: # 调整节点的子节点 想象一下树的结构,乘以2到达下一层 child = root*2 + 1 if child > end : break if child+1 <= end and nums[child] < nums[child+1]: #如果子节点小于后一位数,就+1 使用较大的子节点判断 child = child+1 if nums[root] < nums[child]: # 如果根节点小于子节点,就调换位置 nums[root], nums[child] = nums[child], nums[root] root = child # 根节点和子节点调换了位置,这个时候把根节点的下标改为子节点下标,判断更改后的子节点是否符合父节点的要求 else: break
def shellSort(nums): n = len(nums) step = round(n/2) # 初始步长为数组的一半,round是用来四舍五入的 #步长从N/2开始,每次减半,直至为1 while step > 0: for i in range(step, n):#设置步长step,则每次就像是nums[i]和nums[i+step]对比,进行插入排序,就向前面说的列进行比较 temp = nums[i] j = i while j >= step and nums[j-step] > temp: #插入排序一样,调换位置 nums[j] = nums[j-step] j = j - step nums[j] = temp step = round(step/2) # 重新设置步长 return nums