python之树的实现
一、前言
树的术语是生物学、家谱学和几何学术语的一个特殊混合体。它很好的表示了层级结构,它的两个主要特征:
- 每个项都有多个子节点。
- 除了叫做根(树最顶端的节点)的特殊项,所有其他的项都只有一个父节点。
普通的树和二叉树的递归定义:
- 普通的树------普通的树要么为空,要么包含一个有限的节点的集合T。有一个和所有其他节点不同的节点r,称为根,此外,集合T-{r}被划分为不相连的子集,每个子集都是一个普通的树。
- 二叉树------一个二叉树要么为空,要么包含一个根节点,外加一个左子树和一个右子树,每个子树都是一个二叉树。
二、二叉搜索树(Binary Search Tree,BST)
在一个BST中,给定节点的左子树中的节点要小于它,其右子树中的节点要大于给定的节点。
2.1 二叉搜索树接口中的方法
BST方法 | 作用 |
tree.isEmpty() | 如果为空,返回True,否则返回False |
tree.__len__() | 返回树中元素的数目 |
tree.__iter__() | 对树进行一次前向遍历 |
tree.__str__() | 返回字符串,表示树的形状 |
tree.__contains__(item) | 如果item在树中,返回True,否则返回False |
tree.__add__(otherTree) | 返回一个新树,内容为tree和otherTree的内容 |
tree.__eq__(anyObject) | 若tree==otherTree,返回True,否则返回False |
tree.clear() | 让树变成空树 |
tree.add(item) | 将item添加到树中适当的位置 |
tree.remove(item) | 从树中删除item,先验条件:item在树中 |
tree.replace(item,newItem) | 使用newItem替代树中匹配的项,并返回匹配的项 |
tree.inorder() | 返回一个迭代器,对树执行中序遍历 |
tree.postorder() | 返回一个迭代器,对树执行后序遍历 |
tree.levelorder() | 返回一个迭代器,对树执行层序遍历 |
2.2代码实现
2.2.1 创建抽象集类,并保存为abstractcollection.py文件,具体代码见博客:https://blog.csdn.net/lzh_12345/article/details/79759960中的“二、利用链表实现栈”之2.1的代码。
2.2.2创建二叉搜索树节点类BSTNode,并保存为bstnode.py文件
class BSTNode(object):"""Represents a node for a linked binary search tree."""def __init__(self, data, left = None, right = None):self.data = dataself.left = leftself.right = right
2.2.3创建LinkedStack和LinkedQueue类,并分别保存为linkedstack.py和linkedqueue.py文件。
LinkedStack类的具体代码:见博客:https://blog.csdn.net/lzh_12345/article/details/79759960中的“二、利用链表实现栈”。
LinkedQueue类的具体代码:见博客:https://blog.csdn.net/lzh_12345/article/details/79762861中的“二、队列的链表实现”。
2.2.4 链表实现BST
from abstractcollection import AbstractCollection
from bstnode import BSTNode
from linkedstack import LinkedStack
from linkedqueue import LinkedQueueclass LinkedBST(AbstractCollection):"""An link-based binary search tree implementation."""def __init__(self, sourceCollection = None):"""Sets the initial state of self, which includes thecontents of sourceCollection, if it's present."""self._root = NoneAbstractCollection.__init__(self, sourceCollection)# Accessor methodsdef __str__(self):"""Returns a string representation with the tree rotated90 degrees counterclockwise."""def recurse(node, level):s = ""if node != None:s += recurse(node.right, level + 1)s += "| " * levels += str(node.data) + "\n"s += recurse(node.left, level + 1)return sreturn recurse(self._root, 0)def __iter__(self):"""Supports a preorder traversal on a view of self."""if not self.isEmpty():stack = LinkedStack()stack.push(self._root)while not stack.isEmpty():node = stack.pop()yield node.dataif node.right != None:stack.push(node.right)if node.left != None:stack.push(node.left)def preorder(self):"""Supports a preorder traversal on a view of self."""return Nonedef inorder(self):"""Supports an inorder traversal on a view of self."""lyst = list()def recurse(node):if node != None:recurse(node.left)lyst.append(node.data)recurse(node.right)recurse(self._root)return iter(lyst)def postorder(self):"""Supports a postorder traversal on a view of self."""return Nonedef levelorder(self):"""Supports a levelorder traversal on a view of self."""return Nonedef __contains__(self, item):"""Returns True if target is found or False otherwise."""return self.find(item) != Nonedef find(self, item):"""If item matches an item in self, returns thematched item, or None otherwise."""def recurse(node):if node is None:return Noneelif item == node.data:return node.dataelif item < node.data:return recurse(node.left)else:return recurse(node.right)return recurse(self._root)# Mutator methodsdef clear(self):"""Makes self become empty."""self._root = Noneself._size = 0def add(self, item):"""Adds item to the tree."""# Helper function to search for item's position def recurse(node):# New item is less, go left until spot is foundif item < node.data:if node.left == None:node.left = BSTNode(item)else:recurse(node.left)# New item is greater or equal, # go right until spot is foundelif node.right == None:node.right = BSTNode(item)else:recurse(node.right)# End of recurse# Tree is empty, so new item goes at the rootif self.isEmpty():self._root = BSTNode(item)# Otherwise, search for the item's spotelse:recurse(self._root)self._size += 1def remove(self, item):"""Precondition: item is in self.Raises: KeyError if item is not in self.postcondition: item is removed from self."""if not item in self:raise KeyError("Item not in tree.""")# Helper function to adjust placement of an itemdef liftMaxInLeftSubtreeToTop(top):# Replace top's datum with the maximum datum in the left subtree# Pre: top has a left child# Post: the maximum node in top's left subtree# has been removed# Post: top.data = maximum value in top's left subtreeparent = topcurrentNode = top.leftwhile not currentNode.right == None:parent = currentNodecurrentNode = currentNode.righttop.data = currentNode.dataif parent == top:top.left = currentNode.leftelse:parent.right = currentNode.left# Begin main part of the methodif self.isEmpty(): return None# Attempt to locate the node containing the itemitemRemoved = NonepreRoot = BSTNode(None)preRoot.left = self._rootparent = preRootdirection = 'L'currentNode = self._rootwhile not currentNode == None:if currentNode.data == item:itemRemoved = currentNode.databreakparent = currentNodeif currentNode.data > item:direction = 'L'currentNode = currentNode.leftelse:direction = 'R'currentNode = currentNode.right# Return None if the item is absentif itemRemoved == None: return None# The item is present, so remove its node# Case 1: The node has a left and a right child# Replace the node's value with the maximum value in the# left subtree# Delete the maximium node in the left subtreeif not currentNode.left == None \and not currentNode.right == None:liftMaxInLeftSubtreeToTop(currentNode)else:# Case 2: The node has no left childif currentNode.left == None:newChild = currentNode.right# Case 3: The node has no right childelse:newChild = currentNode.left# Case 2 & 3: Tie the parent to the new childif direction == 'L':parent.left = newChildelse:parent.right = newChild# All cases: Reset the root (if it hasn't changed no harm done)# Decrement the collection's size counter# Return the itemself._size -= 1if self.isEmpty():self._root = Noneelse:self._root = preRoot.leftreturn itemRemoveddef replace(self, item, newItem):"""If item is in self, replaces it with newItem andreturns the old item, or returns None otherwise."""probe = self._rootwhile probe != None:if probe.data == item:oldData = probe.dataprobe.data = newItemreturn oldDataelif probe.data > item:probe = probe.leftelse:probe = probe.rightreturn None
2.2.5 测试文件
from linkedbst import LinkedBSTdef main():tree = LinkedBST()print("Adding D B A C F E G")tree.add("D")tree.add("B")tree.add("A")tree.add("C")tree.add("F")tree.add("E")tree.add("G")print("\nExpect True for A in tree: ", "A" in tree)print("\nString:\n" + str(tree))clone = LinkedBST(tree)print("\nClone:\n" + str(clone))print("Expect True for tree == clone: ", tree == clone)print("\nFor loop: ", end="")for item in tree:print(item, end=" ")print("\n\ninorder traversal: ", end="")for item in tree.inorder(): print(item, end = " ")print("\n\npreorder traversal: ", end="")for item in tree.preorder(): print(item, end = " ")print("\n\npostorder traversal: ", end="")for item in tree.postorder(): print(item, end = " ")print("\n\nlevelorder traversal: ", end="")for item in tree.levelorder(): print(item, end = " ")print("\n\nRemoving all items:", end = " ")for item in "ABCDEFG":print(tree.remove(item), end=" ")print("\n\nExpect 0: ", len(tree))tree = LinkedBST(range(1, 16))print("\nAdded 1..15:\n" + str(tree))lyst = list(range(1, 16))import randomrandom.shuffle(lyst)tree = LinkedBST(lyst)print("\nAdded ", lyst, "\n" + str(tree))if __name__ == "__main__":main()
python之树的实现相关推荐
- python数据结构 树_python 数据结构四 之 二叉树和树
python数据结构教程第四课 树形结构是复杂结构中最简单的一类,这是一类非常重要的结构,在实际中使用广泛,反映了许多计算过程的抽象结构 一.简介 1.树 2.二叉树 二.二叉树和树的抽象数据类型(A ...
- python中plotly绘制树地图_聚类分析python画树状图--Plotly(dendrogram)用法解析 - 人人都是架构师...
1.前言 聚类分析是机器学习和数据分析中非常常见的分类方法, 当我们用到层次聚类(系统聚类)时,最常用的分析方法就是绘制树状图, 比较常见的统计软件像SPSS.SAS.R等都可以直接绘制树状图,比较简 ...
- python 对象树
1.python 对象树 python的继承树中的每个节点即一个命名空间,最底下的叶子为对象实例,对象实例通过 __class__ 钩子与上边的类节点连接,类通过__base__钩子与更高的超类连接. ...
- python 常量类用法_token --- 与Python解析树一起使用的常量 — Python 3.10.0a3 文档
token --- 与Python解析树一起使用的常量¶ This module provides constants which represent the numeric values of le ...
- python token_token --- 与Python解析树一起使用的常量 — Python 3.8.6 文档
token --- 与Python解析树一起使用的常量¶ 此模块提供表示解析树(终端令牌)的叶节点的数值的常量. 请参阅 Python 发行版中的文件 Grammar/Grammar ,以获取语言语法 ...
- python token_token --- 与Python解析树一起使用的常量 — Python 3.9.0 文档
token --- 与Python解析树一起使用的常量¶ 此模块提供表示解析树(终端令牌)的叶节点的数值的常量. 请参阅 Python 发行版中的文件 Grammar/Grammar ,以获取语言语法 ...
- Python计算树模型(随机森林、xgboost等)的特征重要度及其波动程度:基于熵减的特征重要度计算及可视化、基于特征排列的特征重要性(feature permutation)计算及可视化
Python计算树模型(随机森林.xgboost等)的特征重要度及其波动程度:基于熵减的特征重要度计算及可视化.基于特征排列的特征重要性(feature permutation)计算及可视化 目录
- python线段树编写,很冗长,不过不难理解。
python线段树编写 前言 一.题目及代码编写 二.补充说明 三.总结 前言 以LC 729. 我的日程安排表 I 为例 这道题不推荐使用这种解法 非常的慢,而且代码超级容易记错! 你没看错 记错! ...
- python数据结构树和二叉树,python数据结构树和二叉树简介
一.树的定义 树形结构是一类重要的非线性结构.树形结构是结点之间有分支,并具有层次关系的结构.它非常类似于自然界中的树. 树的递归定义: 树(Tree)是n(n≥0)个结点的有限集T,T为空时称为空树 ...
- 用python画树_Python+Turtle动态绘制一棵树实例分享
本文实例主要是对turtle的使用,实现Python+turtle动态绘制一棵树的实例,具体代码: # drawtree.py from turtle import Turtle, mainloop ...
最新文章
- 如何修改hosts文件?
- 【C++】C++0x :: Introduction to some amazing features
- 3种python调用其他脚本的方法,你还知道其他的方法吗?
- mysql 提高事物效率_怎么提高向mysql中插入数据的效率-问答-阿里云开发者社区-阿里云...
- 严重: StandardServer.await: create[8005]:
- 【Linux】一步一步学Linux——rename命令(36)
- vue 关于solt得用法
- time包中Parse和Format的区别
- linux 离线安装mysql_Linux系统安装MySQL(离线安装)
- Python深入06 Python的内存管理
- linux的帮助命令及区别,linux经常使用命令以及帮助命令
- jmeter用Firefox录制https协议证书问题解决
- 基于战舰V3的NRF24L01模块的原理剖析及应用
- 疯狂java讲义第二章课后习题答案
- 极域电子教室中计算机图标对齐,极域电子教室使用手册整理,新手必备
- 怎样访问ftp服务器的文件,访问ftp服务器文件夹
- 2023年南昌大学电子信息考研考情与难度、参考书及上岸前辈经验
- 遍历出List<Map>的Key / Value
- IDEA2017配置springmvc遇到的错误
- Java XLS 转 XLSX