python算法(三)——树、二叉树、AVL树

简介: python算法(三)——树、二叉树、AVL树

一、树

1、模拟文件系统

class Node:
    def __init__(self, name, type='dir'):
        self.name = name
        self.type = type  # "dir" or "file"
        self.children = []
        self.parent = None
    def __repr__(self):
        return self.name
class FileSystemTree:
    def __init__(self):
        self.root = Node("/")
        self.now = self.root
    def mkdir(self, 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):  # 切换到name目录
        if name[-1] != "/":
            name += "/"
        if name == "../":  # 向上切换到parent
            self.now = self.now.parent
            return
        for child in self.now.children:  # 向下切换
            if child.name == name:
                self.now = child
                return
        else:
            raise ValueError("invalid dir")
tree = FileSystemTree()
tree.mkdir("var/")
tree.mkdir("bin/")
tree.mkdir("usr/")
print(tree.now)  # 输出”\“
print(tree.now.children)  # 输出[var/, bin/, usr/]
tree.cd("bin/")
print(tree.now)  # 输出 bin\
tree.cd("../")
print(tree.now)  # 输出”\“


二、二叉树

度不超过2的树。

二叉树的链式存储:将二叉树的节点定义为一个对象,节点之间通过类似链表的链接方式来连接。

class BiTreeNode:
    def __init__(self,data):
        self.data=data
        self.lchild=None    #左孩子
        self.rchild=None    #右孩子


1、二叉树的遍历


前序遍历:EACBDGF

中序遍历:ABCDEGF

后序遍历:BDCAFGE

层次遍历:EAGCFBD

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):  # 前序遍历[E[A[C[BD]]][G[F]]
    if root:
        print(root.data, end=',')
        pre_order(root.lchild)
        pre_order(root.rchild)
def in_order(root):  # 中序遍历[A[BCD]]E[GF]
    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=',')
from collections import deque
def level_order(root):  # 层次遍历
    queue = deque()
    queue.append(root)
    while len(queue) > 0:
        node = queue.popleft()
        print(node.data, end=',')
        if node.lchild:
            queue.append(node.lchild)
        if node.rchild:
            queue.append(node.rchild)

2、二叉搜索树

二叉搜索树是一颗二叉树且满足性质:设x是二叉树的一个节点,如果y是x左子树的一个节点,那么y.key≤x.key;如果y是x右子树的一个节点,那么y.key≤≥.key。


2.1二叉搜索树的插入、搜索、删除


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 val in li:
                self.insert(val)
    def insert(self, val):
        # 插入
        p = self.root
        if not p:
            self.root = BiTreeNode(val)
            return
        while True:
            if val < p.data:
                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
    def query(self, val):
        # 查找
        p = self.root
        while p:
            if p.data < val:
                p = p.rchild
            elif p.data > val:
                p = p.lchild
            else:
                return p
        return None
    def remove_node_1(self, node):
        # 情况1:node是叶子节点
        if not node.parent:  # node为根节点
            self.root = None
        if node == node.parent.lchild:  # node是它父亲的左孩子
            node.parent.lchild = None
        else:  # node是它父亲的右孩子
            node.parent.rchild = None
    def remove_node_2_1(self, node):
        # 情况2_1:node只有一个左孩子
        if not node.parent:  # 根节点
            self.root = node.lchild
            node.lchild.parent = None
        elif node == node.parent.lchild:
            node.parent.lchild = node.lchild
            node.lchild.parent = node.parent
        else:
            node.parent.rchild = node.lchild
            node.lchild.parent = node.parent
    def remove_node_2_2(self, node):
        #   情况2_2:node只有一个右孩子
        if not node.parent:
            self.root = node.rchild
        elif node == node.parent.lchild:
            node.parent.lchild = node.rchild
            node.rchild.parent = node.parent
        else:
            node.parent.rchild = node.rchild
            node.rchild.parent = node.parent
    def delete(self, val):
        if self.root:  # 不是空树
            node = self.query(val)
            if not node:  # node不存在
                return False
            if not node.lchild and not node.rchild:  # 情况1
                self.remove_node_1(node)
            elif not node.rchild:  # 情况2_1
                self.remove_node_2_1(node)
            elif not node.lchild:  # 情况2_2
                self.remove_node_2_2(node)
            else:  # 情况3:两个孩子都有
                min_node = node.lchild
                while min_node.lchild:
                    min_node = min_node.lchild
                node.data = min_node.data
                # 删除min_node(为叶子节点或者只有一个右孩子)
                if min_node.rchild:
                    self.remove_node_2_2(min_node)
                else:
                    self.remove_node_1(min_node)
    def in_order(self, root):  # 中序遍历
        if root:
            self.in_order(root.lchild)
            print(root.data, end=',')
            self.in_order(root.rchild)
    def pre_order(self, root):  # 前序遍历
        if root:
            print(root.data, end=',')
            self.pre_order(root.lchild)
            self.pre_order(root.rchild)
tree = BST([5, 17, 35, 2, 11, 29, 38, 9, 8])
tree.in_order(tree.root)  # 对于二叉搜索树,其中序遍历输出结果是升序排列
print("")
tree.pre_order(tree.root)
print("")
print(tree.query(2).data)  # 搜索
tree.delete(4)
tree.in_order(tree.root)

3、AVL树


from bst import BiTreeNode, BST #将2.1处的代码存为bst.py,此处调用
class AVLNode(BiTreeNode):
    def __init__(self, data):
        BiTreeNode.__init__(self, data)
        self.bf = 0
class AVLTree(BST):
    def __init__(self, li=None):
        BST.__init__(self, li)
    def rotate_left(self, p, c):  # 左旋
        s2 = c.lchild
        p.rchild = s2
        if s2:
            s2.parent = p
        c.lchild = p
        p.parent = c
        p.bf = 0
        c.bf = 0
        return c
    def rotate_right(self, p, c):  # 右旋
        s2 = c.rchild
        p.lchild = s2
        if s2:
            s2.parent = p
        c.rchild = p
        p.parent = c
        p.bf = 0
        c.bf = 0
        return c
    def rotate_right_left(self, p, c):  # 右旋——左旋
        g = c.lchild
        s3 = g.rchild
        c.lchild = s3
        if s3:
            s3.parent = c
        g.rchild = c
        c.parent = g
        s2 = g.lchild
        p.rchild = s2
        if s2:
            s2.parent = p
        g.lchild = p
        p.parent = g
        # 更新bf
        if g.bf > 0:  # g.bf==1
            p.bf = -1
            c.bf = 0
        else:  # g.bf==-1
            p.bf = 0
            c.bf = 1
        g.bf = 0
        return g
    def rotate_left_right(self, p, c):  # 左旋——右旋
        g = c.rchild
        s2 = g.lchild
        c.rchild = s2
        if s2:
            s2.parent = c
        g.lchild = c
        c.parent = g
        s3 = g.rchild
        p.lchild = s3
        if s3:
            s3.parent = p
        g.rchild = p
        p.parent = g
        # 更新bf
        if g.bf < 0:
            p.bf = 1
            c.bf = 0
        else:
            p.bf = 0
            c.bf = -1
        g.bf = 0
        return g
    def insert(self, val):
        # 1、做插入
        p = self.root
        if not p:
            self.root = AVLNode(val)
            return
        while True:
            if val < p.data:
                if p.lchild:
                    p = p.lchild
                    node = p.lchild  # node存储的是插入的节点
                else:
                    p.lchild = AVLNode(val)
                    p.lchild.parent = p
                    node = p.lchild  # node存储的是插入的节点
                    break
            elif val > p.data:
                if p.rchild:
                    p = p.rchild
                else:
                    p.rchild = AVLNode(val)
                    p.rchild.parent = p
                    node = p.rchild
                    break
            else:
                return
        # 2、更新bf参数
        while node.parent:  # node.parent不空
            if node.parent.lchild == node:  # 传递是从左子树来的,更新后的node.parent的bf-=1
                if node.parent.bf < 0:  # 原来的node。parent。bf==-1,更新后变成-2
                    # 做旋转
                    g = node.parent.parent  # 用于连接旋转之后的子树
                    x = node.parent  # 旋转之前的子树的根
                    if node.bf > 0:
                        n = self.rotate_left_right(node.parent, node)
                    else:
                        n = self.rotate_right(node.parent, node)
                elif node.parent.bf > 0:  # 原来的node.parent.bf=1,更新之后变成0
                    node.parent.bf = 0
                    break
                else:  # 原来的node.parent.bf=0,更新之后变成-1
                    node.parent.bf = -1
                    node = node.parent
                    continue
            else:  # 传递是从右子树来的,更新后的node.parent的bf+=1
                if node.parent.bf > 0:  # 原来的node。parent。bf==1,更新后变成2
                    # 做旋转
                    g = node.parent.parent
                    x = node.parent
                    if node.bf < 0:
                        n = self.rotate_right_left(node.parent, node)
                    else:
                        n = self.rotate_left(node.parent, node)
                elif node.parent.bf < 0:  # 原来的node。parent。bf==-1,更新后变成0
                    node.parent.bf = 0
                    break
                else:  # 原来的node.parent.bf=0,更新之后变成1
                    node.parent.bf = 1
                    node.parent = node
                    continue
            # 连接旋转之后的子树
            n.parent = g
            if g:
                if x == g.lchild:
                    g.lchild = n
                else:
                    g.rchild = n
                break
            else:
                self.root = n
                break
tree = AVLTree([9, 8, 7, 6, 5, 4, 3, 2, 1])
tree.pre_order(tree.root)
print("")
tree.in_order(tree.root)


目录
相关文章
|
18天前
|
机器学习/深度学习 人工智能 算法
猫狗宠物识别系统Python+TensorFlow+人工智能+深度学习+卷积网络算法
宠物识别系统使用Python和TensorFlow搭建卷积神经网络,基于37种常见猫狗数据集训练高精度模型,并保存为h5格式。通过Django框架搭建Web平台,用户上传宠物图片即可识别其名称,提供便捷的宠物识别服务。
200 55
|
6天前
|
存储 缓存 监控
局域网屏幕监控系统中的Python数据结构与算法实现
局域网屏幕监控系统用于实时捕获和监控局域网内多台设备的屏幕内容。本文介绍了一种基于Python双端队列(Deque)实现的滑动窗口数据缓存机制,以处理连续的屏幕帧数据流。通过固定长度的窗口,高效增删数据,确保低延迟显示和存储。该算法适用于数据压缩、异常检测等场景,保证系统在高负载下稳定运行。 本文转载自:https://www.vipshare.com
99 66
|
10天前
|
存储 运维 监控
探索局域网电脑监控软件:Python算法与数据结构的巧妙结合
在数字化时代,局域网电脑监控软件成为企业管理和IT运维的重要工具,确保数据安全和网络稳定。本文探讨其背后的关键技术——Python中的算法与数据结构,如字典用于高效存储设备信息,以及数据收集、异常检测和聚合算法提升监控效率。通过Python代码示例,展示了如何实现基本监控功能,帮助读者理解其工作原理并激发技术兴趣。
47 20
|
3天前
|
算法 网络协议 Python
探秘Win11共享文件夹之Python网络通信算法实现
本文探讨了Win11共享文件夹背后的网络通信算法,重点介绍基于TCP的文件传输机制,并提供Python代码示例。Win11共享文件夹利用SMB协议实现局域网内的文件共享,通过TCP协议确保文件传输的完整性和可靠性。服务器端监听客户端连接请求,接收文件请求并分块发送文件内容;客户端则连接服务器、接收数据并保存为本地文件。文中通过Python代码详细展示了这一过程,帮助读者理解并优化文件共享系统。
|
8天前
|
存储 算法 Python
文件管理系统中基于 Python 语言的二叉树查找算法探秘
在数字化时代,文件管理系统至关重要。本文探讨了二叉树查找算法在文件管理中的应用,并通过Python代码展示了其实现过程。二叉树是一种非线性数据结构,每个节点最多有两个子节点。通过文件名的字典序构建和查找二叉树,能高效地管理和检索文件。相较于顺序查找,二叉树查找每次比较可排除一半子树,极大提升了查找效率,尤其适用于海量文件管理。Python代码示例包括定义节点类、插入和查找函数,展示了如何快速定位目标文件。二叉树查找算法为文件管理系统的优化提供了有效途径。
39 5
|
8天前
|
存储 缓存 算法
探索企业文件管理软件:Python中的哈希表算法应用
企业文件管理软件依赖哈希表实现高效的数据管理和安全保障。哈希表通过键值映射,提供平均O(1)时间复杂度的快速访问,适用于海量文件处理。在Python中,字典类型基于哈希表实现,可用于管理文件元数据、缓存机制、版本控制及快速搜索等功能,极大提升工作效率和数据安全性。
41 0
|
Python
python实现二叉树的创建和遍历
python实现二叉树的创建和遍历
314 0
|
算法 Python 机器学习/深度学习
|
28天前
|
人工智能 数据可视化 数据挖掘
探索Python编程:从基础到高级
在这篇文章中,我们将一起深入探索Python编程的世界。无论你是初学者还是有经验的程序员,都可以从中获得新的知识和技能。我们将从Python的基础语法开始,然后逐步过渡到更复杂的主题,如面向对象编程、异常处理和模块使用。最后,我们将通过一些实际的代码示例,来展示如何应用这些知识解决实际问题。让我们一起开启Python编程的旅程吧!