二分查找
只能作用于有序的顺序表
def binary_search_1(alist,item):
"""二分查找"""
n = len(alist)
if n > 0:
mid = n//2
if alist[mid] == item:
return True
elif item < alist[mid]:
return binary_search_1(alist[:mid],item)
else:
return binary_search_1(alist[mid+1:,item])
return False
def binary_search_2(alist,item):
"""二分查找,非递归"""
n = len(alist)
first = 0
last = n-1
while first <= last:
mid = (first+last)//2
if alist[mid] == item:
return True
elif item < alist[mid]:
last = mid-1
else:
first = mid+1
return False
if __name__ == '__main__':
alist = [2,4,6,8,10,12,25,28,30]
print(binary_search_1(alist,6))
print(binary_search_2(alist, 6))
树与树的算法
根朝上叶朝下的结构
注意:
- 每个结点有零个或者多个子结点
- 没有父结点的结点称为根结点
- 每一个非根结点有且只有一个父结点
- 除了根结点,每个子结点可以分为多个不相交的子树
术语:
结点的度:每个结点的子树个数
树的度:一棵树中,最大结点的度称为树的度
叶结点或终端结点:度为0的结点
父亲结点或父结点:若一个结点含有子结点,则这个结点称为其子结点的父结点
孩结点,子结点:该结点的下一级
兄弟结点:同有一个父结点的不同结点
结点的层级:兄弟结点为同一层
树的高度和深度:最深层次
堂兄弟结点:父结点在同一层级上的结点互为堂兄弟
结点的祖先:到达该结点所经过的所有结点
子孙:以某结点为根的子树中任一结点都称为该结点的子孙
森林:m(m>=1)棵互不相交的树的集合称为森林
树的种类
无序树:树中任意节点的子结点之间没有顺序关系,也称自由树
有序树:树中任意节点的子结点之间有顺序关系,
1. 二叉树:每个结点最多只有两个子结点
完全二叉树:除最底层,其余层级结点达到最大数量
满二叉树:所以层级结点达到最大数量
2. 平衡二叉树:任意两个子树的深度差不超过1
3. 排序二叉树:对任意结点,其左子树所有结点值均小于或等于该结点的值其右子树所有结点值均大于或等于该结点的值
4. 霍夫曼树
5. B树
常见的一些树的应用场景
- xml,html
- 路由协议
- MySQL数据库索引
- 文件系统目录结构
- 很多经典的AI算法
二叉树的性质
- 第n层至多2^(n-1)个结点
- 深度为n的二叉树至多有2^n-1个结点
- 任意二叉树,当其叶结点数为N0,且度数为2的结点总数为N2,则N0=N2+1
- 有n个结点的完全二叉树深度为log2(n+1)
- 完全二叉树,从上至下,从左至右编号,编号为n的结点,其左孩子编号为2n,右孩子编号为2n+1,其双亲编号为n/2(除n为根时)
树的遍历
class Node(object):
""" """
def __init__(self,item):
self.elem = item
self.lchild = None
self.rchild = None
class Tree(object):
"""二叉树"""
def __init__(self):
self.root = None
def add(self,item):
node = Node(item)
if self.root is None:
self.root = node
return
queue = [self.root]
while queue:
cur_node = queue.pop(0)
if cur_node.lchild is None:
cur_node.lchild = node
return
else:
queue.append(cur_node.lchild)
if cur_node.rchild is None:
cur_node.rchild = node
return
else:
queue.append(cur_node.rchild)
def breadth_travel(self):
"""广度遍历"""
if self.root is None:
return
queue = [self.root]
while queue:
cur_node = queue.pop(0)
print(cur_node.elem)
if cur_node.lchild is not None:
queue.append(cur_node.lchild)
if cur_node.rchild is not None:
queue.append(cur_node.rchild)
def preorder(self,node):
"""先序排列"""
if node == None:
return
print(node.elem,end=' ')
self.preorder(node.lchild)
self.preorder(node.rchild)
def inorder(self,node):
"""中序遍历"""
if node is None:
return
self.inorder(node.lchild)
print(node.elem,end=' ')
self.inorder(node.rchild)
def postorder(self,node):
"""后序遍历"""
if node is None:
return
self.postorder(node.lchild)
self.postorder(node.rchild)
print(node.elem,end=' ')
if __name__ == '__main__':
tree = Tree()
tree.add(0)
tree.add(1)
tree.add(2)
tree.add(3)
tree.add(4)
tree.add(5)
tree.add(6)
tree.add(7)
tree.add(8)
tree.add(9)
tree.breadth_travel()
print(' ')
tree.preorder(tree.root)
print(' ')
tree.inorder(tree.root)
print(' ')
tree.postorder(tree.root)