1006 字
5 分钟
查找算法笔记
查找
顺序查找
无序表查找代码
def sequentialSearch(alist,item): pos = 0 found = False
while pos < len(alist) and not found: if alist[pos] == item: found = True else: pos = pos + 1 return found有序表查找代码
def orderedSequentialSearch(alist,item): pos = 0 found = False stop = False
while pos < len(alist) and not found and not stop: if alist[pos] == item: found = True else: if alist[pos] > item: stop = True else: pos = pos + 1 return found二分查找
def binarySearch(alist,item): first = 0 last = len(alist) - 1 found = False
while first <= last and not found: midpoint = (first + last)//2 if alist[midpoint] == item: found = True else: if item < alist[midpoint]: last = midpoint - 1 else: first = midpoint + 1 return found递归实现
def binarySearch(alist,item): if len(alist) == 0: return False else: midpoint = len(alist)//2 if alist[midpoint] == item: return True else: if item < alist[midpoint]: return binarySearch(alist[:midpoint],item) else: return binarySearch(alist[midpoint+1:],item)复杂度为O(log n)
排序
冒泡排序 时间复杂度O(n^2)
def bubbleSort(alist): for passnum in range(len(alist)-1,0,-1): for i in range(passnum): if alist[i]>alist[i+1]: temp = alist[i] alist[i] = alist[i+1] alist[i+1] = temp插入排序 时间复杂度O(n^2)
nums = [5,3,6,4,1,2,8,7]for i in range(1,len(nums)): for j in range(i): if nums[i] < nums[j]: ins = nums[i] nums.pop(i) nums.insert(j,ins) breakprint(nums)谢尔排序 时间复杂度O(n^2)
谢尔排序是已插入排序为基础,将无序表分割为多个字列表,每个子列表都执行插入排序
def shellSort(alist): sublistcount = len(alist) // 2 while sublistcount > 0:
for startposition in range(sublistcount): gapInsertionSort(alist,startposition,sublistcount)
print("After increments of size",sublistcount,"The list is",alist)
sublistcount = sublistcount // 2
def gapInsertionSort(alist,start,gap): for i in range(start+gap,len(alist),gap):
currentvalue = alist[i] position = i
while position >= gap and alist[position-gap] > currentvalue: alist[position] = alist[position-gap] position = position - gap
alist[position] = currentvalue选择排序 时间复杂度O(n^2)
nums = [5,3,6,4,1,2,8,7]res = []while len(nums): minInd = 0 for i in range(1,len(nums)): if nums[i] < nums[minInd]: minInd = i temp = nums[minInd] nums.pop(minInd) res.append(temp)print(res)归并排序 时间复杂度O(n log n)
分治策略在排序中的应用,归并排序是递归算法,思路是将数据表持续分裂为两半,对两半分别进行归并排序
传统版本代码:
def mergeSort(alist): print("Splitting",alist) if len(alist) > 1: #基本结束条件 mid = len(alist) // 2 leftHalf = alist[:mid] rightHalf = alist[mid:]
mergeSort(leftHalf) #递归调用自身 mergeSort(rightHalf)
i = j = k = 0 while i < len(leftHalf) and j < len(rightHalf): #归并过程 if leftHalf[i] < rightHalf[j]: alist[k] = leftHalf[i] i = i + 1 else: alist[k] = rightHalf[j] j = j + 1 k = k + 1
while i < len(leftHalf): #归并左半部剩余项 alist[k] = leftHalf[i] i = i + 1 k = k + 1
while j < len(rightHalf): #归并右半部剩余项 alist[k] = rightHalf[j] j = j + 1 k = k + 1
print("Merging",alist)更Pythonic的代码(可读性更高):
def merge_sort(lst): #递归结束条件 if len(lst) <= 1: return lst
#递归调用自身 middle = len(lst) // 2 left = merge_sort(lst[:middle]) right = merge_sort(lst[middle:])
#合并左右半部,完成排序 merged = [] while left and right: if left[0] < right[0]: merged.append(left.pop(0)) else: merged.append(right.pop(0)) merged.extend(right if right else left) return merged快速排序 时间复杂度O(n log n)
思路:根据一个基准值,将列表分为两部分,一部分小于基准值,一部分大于基准值,然后对两部分分别进行快速排序
def partition(alist,first,last): # 选取“首元素”为基准值(pivot)。这种选法实现简单,但在近乎有序数据上可能退化较明显 pivotvalue = alist[first]
# leftmark 从左向右找“> pivot”的元素;rightmark 从右向左找“< pivot”的元素 leftmark = first + 1 rightmark = last
done = False while not done: # 左指针跳过所有 <= pivot 的元素 while leftmark <= rightmark and alist[leftmark] <= pivotvalue: leftmark = leftmark + 1
# 右指针跳过所有 >= pivot 的元素 while alist[rightmark] >= pivotvalue and rightmark >= leftmark: rightmark = rightmark - 1
# 指针交错,说明分区扫描完成 if rightmark < leftmark: done = True else: # 交换两侧“放错边”的元素,让小的去左边、大的去右边 temp = alist[leftmark] alist[leftmark] = alist[rightmark] alist[rightmark] = temp
# 把 pivot 放到最终位置:其左侧都 <= pivot,右侧都 >= pivot temp = alist[first] alist[first] = alist[rightmark] alist[rightmark] = temp
return rightmark
def quickSortHelper(alist,first,last): # 递归终止条件:子区间长度为 0 或 1 时天然有序 if first < last: splitpoint = partition(alist,first,last) # 分别对 pivot 左右两侧递归排序 quickSortHelper(alist,first,splitpoint-1) quickSortHelper(alist,splitpoint+1,last)
def quickSort(alist): # 原地排序:直接在 alist 上操作,不额外返回新列表 quickSortHelper(alist,0,len(alist)-1)
alist = [54,26,93,17,77,31,44,55,20]quickSort(alist)print(alist) 分享
如果这篇文章对你有帮助,欢迎分享给更多人!
部分信息可能已经过时









