文章目录
前言
最近正在准备参加蓝桥杯,先打校赛,正在学习算法
一、树的概念
1.树的概念
2.树的实例:模拟文件系统
class Node:
def __init__(self, name=None, type="dir"):
self.name = name
self.type = type
self.children = []
self.parent = None
def __repr__(self):
return self.name
class FileSystemTree:
def __init__(self):
self.root = Node("/")
self.now = self.root # 使指针指向root节点
def mkdir(self, name):
# name 以/结尾 若无/则加上
if name[-1] != "/":
name += "/"
node = Node(name)
self.now.children.append(node)
node.parent = self.now
def ls(self):
return self.now.children
def cd(self, name):
if name[-1] != "/":
name += "/"
if name == "../":
self.now = self.now.parent
return
for child in self.now.children:
if child.name == name:
self.now = child
return
raise ValueError("invalid dir")
tree = FileSystemTree()
tree.mkdir("var/")
tree.mkdir("bin/")
tree.mkdir("usr/")
print(tree.ls())
tree.cd("var/")
tree.mkdir("user/")
print(tree.ls())
tree.cd("../")
print(tree.ls())
二、二叉树的概念
1.二叉树
2.二叉树的遍历
from collections import deque
class BiTreeNode:
def __init__(self, data):
self.data = data
self.lchild = None
self.rchild = None
a = BiTreeNode("A")
b = BiTreeNode("B")
c = BiTreeNode("C")
d = BiTreeNode("D")
e = BiTreeNode("E")
f = BiTreeNode("F")
g = BiTreeNode("G")
e.lchild = a
e.rchild = g
a.rchild = c
c.lchild = b
c.rchild = d
g.rchild = f
root = e
def pre_order(root):
if root: # 前序遍历
print(root.data, end=',')
pre_order(root.lchild)
pre_order(root.rchild)
def in_order(root):
if root: # 如果根存在
in_order(root.lchild)
print(root.data, end=",")
in_order(root.rchild)
def post_order(root):
if root:
post_order(root.lchild)
post_order(root.rchild)
print(root.data, end=",")
def level_order(root):
queue = deque()
queue.append(root)
while len(queue): # 只要队不空
node = queue.popleft()
print(node.data, end=",")
if node.lchild:
queue.append(node.lchild)
if node.rchild:
queue.append(node.rchild)
pre_order(e)
print()
in_order(e)
print()
post_order(e)
print()
level_order(e)
三、二叉搜索树
1.二叉搜索树的概念
2.插入
class BiTreeNode:
def __init__(self, data):
self.data = data
self.lchild = None
self.rchild = None
self.parent = None
class BST:
def __init__(self, li=None):
self.root = None
if li:
for el in li:
self.insert_no_rec(el)
def insert(self, node, val):
if not node:
node = BiTreeNode(val)
elif val < node.data: # 一直往左走直到 触发if not node 创建节点 并相连
node.lchild = self.insert(node.lchild, val)
self.lchild.parent = node
elif val > node.data:
node.rchild = self.insert(node.rchild, val)
return node
def insert_no_rec(self, val):
p = self.root
if not p:
self.root = BiTreeNode(val)
return
while True:
if val < p.data:
# 子树存在就移动p 不存在就直接插
if p.lchild:
p = p.lchild
else:
p.lchild = BiTreeNode(val)
p.lchild.parent = p
return
elif val > p.data:
if p.rchild:
p = p.rchild
else:
p.rchild = BiTreeNode(val)
p.rchild.parent = p
return
else:
return
3.查询
def query(self, node, val):
if not node:
return None
elif node.data > val:
return self.query(node.lchild, val)
elif node.data < val:
return self.query(node.rchild, val)
else:
return node
def query_no_rec(self, val):
p = self.root
while p:
if p.data < val:
p = p.rchild
elif p.data > val:
p = p.lchild
else:
return p
4.删除
a.要删除的节点是叶子节点
b.要删除的节点只有一个孩子节点
c.要删除的节点有两个孩子节点
d.删除的代码实现
def __remove__(self, node):
# 情况1:node是叶子节点 直接删除
if not node.parent: # 如果是根节点
self.root = None
if node == node.parent.lchild: # node是父亲的左孩子
node.parent.lchild = None
else:
node.parent.rchild = None
def __remove_node_21(self, node):
# 情况2:node只有一个左孩子
if not node.parent: # node是根节点
self.root = node.lchild
elif node == node.parent.lchild: # node是父亲的左孩子
node.parent.lchild = node.lchild
node.lchild.parent = node.parent
else: # node是父亲的右孩子
node.parent.rchild = node.lchild
node.lchild.parent = node.parent
def __remove_node_22(self, node):
# 情况2.2:node只有一个右孩子
if not node.parent:
self.root = node.rchild
elif node == node.parent.lchild: # node是父亲的左孩子
node.parent.lchild = node.rchild
node.rhile.parent = node.parent
else: # node是父亲的右孩子
node.parent.rchild = node.rchild
node.rchild.parent = node.parent
def delete(self, val):
if self.root: # 不是空树
node = self.query_no_rec(val) # 先找到这个节点
if not node: # 如果节点不存在、
return False
elif not node.lchild and not node.rchild: # 叶子节点
self.__remove__(node)
elif not node.rchild:
self.__remove_node_21(node)
elif not node.lchild:
self.__remove_node_22(node)
else: # 两个孩子都有 :找右子树的最小值代替该节点
min_node = node.rchild
while min_node.lchild:
min_node = min_node.lchild
node.data = min_node.data
# 删除min_node
if min_node.rchild:
self.__remove_node_22(min_node)
else:
self.__remove_node_21(min_node)