查找
顺序查找—— O ( n ) O(n) O(n)
无序表查找
def sequentialSearch(alist, item):
pos = 0
found = False
while pos < len(alist) and not found:
if alist[pos] == item:
found = True
else:
pos += 1
return found
Case | Best Case | Worst Case | Average Case |
---|---|---|---|
item is present | 1 1 1 | n n n | n / 2 n/2 n/2 |
item is not present | n n n | n n n | n n n |
有序表查找
# 有序表查找:
# 当数字大于目标数字时,说明列表中没有所要查找的数字
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 += 1
return found
Case | Best Case | Worst Case | Average Case |
---|---|---|---|
item is present | 1 1 1 | n n n | n / 2 n/2 n/2 |
item is not present | 1 1 1 | n n n | n / 2 n/2 n/2 |
二分查找—— O ( l o g n ) O(log\ n) O(log n)
二分查找
# 从列表中间开始比对:
# 1.如果列表中间项匹配,则查找结束
# 2.如果不匹配:
# (1)中间项比查找项大:查找项出现在前半部分
# (2)中间项比查找项小:查找项出现在后半部分
# 每次范围缩小一半
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 binarySearch2(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 binarySearch2(alist[:midpoint], item)
else:
return binarySearch2(alist[midpoint + 1:], item)
排序
冒泡排序—— O ( n 2 ) O(n^2) O(n2)
冒泡排序
def bubbleSort(alist):
for passnum in range(len(alist) - 1, 0, -1):
for i in range(passnum):
if alist[i] > alist[i + 1]:
alist[i], alist[i + 1] = alist[i + 1], alist[i]
冒泡排序:性能改进
def shortBubbleSort(alist):
exchanges = True
passnum = len(alist) - 1
while passnum > 0 and exchanges:
exchanges = False
for i in range(passnum):
if alist[i] > alist[i + 1]:
exchanges = True
alist[i], alist[i + 1] = alist[i + 1], alist[i]
passnum -= 1
插入排序—— O ( n 2 ) O(n^2) O(n2)
def insertionSort(alist):
for index in range(1, len(alist)):
# 插入项
currentValue = alist[index]
position = index
# 对比、移动
while position > 0 and alist[position - 1] > currentValue:
alist[position] = alist[position - 1]
position = position - 1
# 插入新项
alist[position] = currentValue
谢尔排序—— O ( n 3 2 ) O(n^\frac{3}{2}) O(n23)
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 l o g n ) O(nlog\ n) O(nlog n)
def mergeSort(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 += 1
else:
alist[k] = righthalf[j]
j = j + 1
k += 1
# 归并左边剩余
while i < len(lefthalf):
alist[k] = lefthalf[i]
i += 1
k += 1
# 归并右边剩余
while j < len(righthalf):
alist[k] = righthalf[j]
j += 1
k += 1
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 ) O(n) O(n)
def partition(alist, first, last):
pivotvalue = alist[first]
leftmark = first + 1
rightmark = last
done = False
while not done:
while leftmark <= rightmark and alist[leftmark] <= pivotvalue:
leftmark = leftmark + 1
while alist[rightmark] >= pivotvalue and rightmark >= leftmark:
rightmark -= 1
if rightmark < leftmark:
done = True
else:
alist[leftmark], alist[rightmark] = alist[rightmark], alist[leftmark]
alist[first], alist[rightmark] = alist[rightmark], alist[first]
return rightmark
def quickSort(alist):
quickSortHelper(alist, 0, len(alist) - 1)
def quickSortHelper(alist, first, last):
if first < last:
splitpoint = partition(alist, first, last)
quickSortHelper(alist, first, splitpoint - 1)
quickSortHelper(alist, splitpoint + 1, last)
散列:Hashing
$ h(item)=item % 散列表大小$
item | Hash Value |
---|---|
54 | 10 |
26 | 4 |
93 | 5 |
17 | 6 |
77 | 0 |
31 | 9 |
完美散列函数
- 压缩性
- 易计算性
- 抗修改性
- 抗冲突性
散列函数设计
折叠法
- 将数据项分段——(隔数翻转)
- 将几段数据相加
- 求余得到散列值
平方取中
- 数据项平方计算
- 取平方数中间两位求余
非数字项
- ASCII码
- 运算
def hash(astring, tablesize):
sum = 0
for pos in range(len(astring)):
sum += ord(astring[pos])
return sum % tablesize
- 变位词:权重因子
冲突解决方案——再散列
开放定址
- 线性探测
- 跳跃式探测:
- skip的值不能被散列表大小整除
- 二次探测
r e h a s h ( p o s ) = ( p o s + s k i p ) % s i z e o f t a b l e rehash(pos)=(pos+skip)\%sizeoftable rehash(pos)=(pos+skip)%sizeoftable
数据项链
抽象数据类型:映射——ADT Map
class HashTable:
def __init__(self):
self.size = 11
self.slots = [None] * self.size
self.data = [None] * self.size
def hashfunction(self, key):
return key % self.size
def rehash(self, oldhash):
return (oldhash + 1) % self.size
def put(self, key, data):
hashvalue = self.hashfunction(key)
# 未冲突
if self.slots[hashvalue] == None:
self.slots[hashvalue] = key
self.data[hashvalue] = data
# 替换
else:
if self.slots[hashvalue] == key:
self.data[hashvalue] = data
# 冲突
else:
nextslot = self.rehash(hashvalue)
while self.slots[nextslot] != None and self.slots[nextslot] != key:
nextslot = self.rehash(nextslot)
if self.slots[nextslot] == None:
self.slots[nextslot] = key
self.data[nextslot] = data
else:
self.data[nextslot] = data
def get(self, key):
startslot = self.hashfunction(key)
data = None
stop = False
found = False
position = startslot
while self.slots[position] != None and not found and not stop:
if self.slots[position] == key:
found = True
data = self.data[position]
else:
position = self.rehash(position)
if position == startslot:
stop = True
return data
def __getitem__(self, item):
return self.get(item)
def __setitem__(self, key, value):
self.put(key, value)
最近在学数学,每天抽一点时间学算法,排序与查找终于看完了,还剩下树和图。
我看的是MOOC 北京大学 陈斌老师的《数据结构与算法python版》,都是干货,个人感觉比那些全是枯燥理论的好学一些