数据结构和算法
常见的数据结构: 数组,队列,栈,链表,堆,树,哈希表
- 队列先进先出;Queue单项队列(from queue import Queue),deque 双向队列(from collections import deque)
- 栈:后进先出;基本方法:push,pop,gettop,is_empty,size
- 链表:经常使用两个指针来解决问题
- 堆:常用来找到最大值或者最小值(构建大顶堆或者小顶堆);堆排序
- 树:二叉树:
度的最大值为2
,
完全二叉树:最下一层有右子树就必须有左子树,叶子节点只能出现在倒数2层或者1层
满二叉树,
哈夫曼树:出叶子节点外,度为2
,
二叉查找树即二叉排序树左子树的所有节点都比根节点小,右子树的所有节点都比根节点大
,
平衡二叉树左子树和右子树的高度差不大于1
- 哈希表:解决冲突的方法:
开放寻址法: 这种方法指定大小,当数据较少时速度很快,节省空间。
链地址法:通过链表,数据较大时可以忽略指针的空间,可动态扩展。
建立公共溢出区:把发生碰撞的放到一个特定的空间中,适合数据不大不小。
再哈希法:会浪费一些时间。
常见的算法
排序算法:冒泡排序;快速排序,直接插入排序;希尔排序,选择排序,二路归并排序,基数排序;计数排序
搜索算法:顺序搜索,折半查找,差值查找,跳跃查找
斐波拉茄数列
# 冒泡排序:两层循环,逐个比较
def bubble_sort(seq):
for i in range(len(seq) - 1):
for j in range(i + 1, len(seq)):
if seq[i] > seq[j]:
seq[i], seq[j] = seq[j], seq[i]
return seq
# 快速排序:找到基准值,大的放右边,小的放左面
def quick_sort(arr):
if len(arr) <= 1:
return arr
pivot = arr[len(arr) // 2]
left = [x for x in arr if x < pivot]
middle = [x for x in arr if x == pivot]
right = [x for x in arr if x > pivot]
return quick_sort(left) + middle + quick_sort(right)
# 插入排序:第一个值有序,让待排元素与有序数列从后向前比较,直到有序
def insert_sort(seq):
for index in range(1, len(seq)):
while (index - 1 >= 0 and seq[index - 1] > seq[index]):
seq[index], seq[index - 1] = seq[index - 1], seq[index]
index = index - 1
return seq
# 希尔排序:缩小增量排序,插入排序是希尔排序的特殊情况。
def shell_sort(seq):
gap = len(seq) // 2
while (gap > 0):
for i in range(gap, len(seq)):
while (i - gap >= 0 and seq[i - gap] > seq[i]):
seq[i - gap], seq[i] = seq[i], seq[i - gap]
i -= gap
gap //= 2
return seq
# 二路归并排序 分分合合
def merge_sort(seq):
if len(seq) < 2:
return seq
mid = len(seq) // 2
left, right = seq[0:mid], seq[mid:]
return merge(merge_sort(left), merge_sort(right))
def merge(left, right):
result = []
while left and right:
result.append(left.pop(0) if left[0] < right[0] else right.pop(0))
if left:
result.extend(left)
if right:
result.extend(right)
return result
# 选择排序,每次选择一个最小值进行排序
def select_sort(seq):
for i in range(len(seq) - 1):
minIndex = i
for j in range(i + 1, len(seq)):
if seq[minIndex] > seq[j]:
minIndex = j
seq[i], seq[minIndex] = seq[minIndex], seq[i]
return seq
# 基数排序:先按照某个元素排序,在按照次要元素排序,最终有序, 基于关键字的排序
def radix_sort(seq):
max_length = len(str(max(seq))) # 最大长度
for i in range(max_length):
ret = [[] for i in range(10)]
# 在按照第二位进行排序的时候需要在生成新的桶
for value in seq:
ret[(value//(10**i))%10].append(value)
seq = [i for item in ret for i in item]
return seq
# 计数排序:不进行比较,让他根据空列表下标回到有序状态
def count_sort(seq:list):
'''
最简单的一种,适用于最大值比较小,并且分布在一个有限的额区间
'''
max_value = max(seq)+1
count = [0]*max_value
for value in seq:
count[value] += 1
# 得到了count数组,然后将数组元素还原
ret = []
# for value,c in enumerate(count):
# if value:
# for _ in range(c):
# ret.append(value)
for i in range(len(count)):
while count[i] > 0:
ret.append(i)
count[i]