python树

树的一些定义

节点

节点是树的基本部分。它可以有一个名称,我们称之为“键”。节点也可以有附加信息。我们将
这个附加信息称为“有效载荷”。虽然有效载荷信息不是许多树算法的核心,但在利用树的应用
中通常是关键的。

边是树的另一个基本部分。边连接两个节点以显示它们之间存在关系。每个节点(除根之
外)都恰好从另一个节点的传入连接。每个节点可以具有多个输出边。

树的根是树中唯一没有传入边的节点。在 Figure 2 中,/ 是树的根。

路径

路径是由边连接节点的有序列表。例如,
Mammal→→Carnivora→→Felidae→→Felis→→Domestica是一条路径。

子节点

具有来自相同传入边的节点 c 的集合称为该节点的子节点。在 Figure 2中,节点 log/,spool/
和 yp/ 是节点 var/ 的子节点。

父节点

具有和它相同传入边的所连接的节点称为父节点。在 Figure 2 中,节点 var/ 是节点 log/,
spool/ 和 yp/ 的父节点。

兄弟

树中作为同一父节点的子节点的节点被称为兄弟节点。节点 etc/ 和 usr/ 是文件系统树中的兄
弟节点。

子树

子树是由父节点和该父节点的所有后代组成的一组节点和边。

叶节点

叶节点是没有子节点的节点。

层数

节点 n 的层数为从根结点到该结点所经过的分支数目。

高度

树的高度等于树中任何节点的最大层数。

树具有以下属性:

  • 树的一个节点被指定为根节点。
  • 除了根节点之外,每个节点 n 通过一个其他节点 p 的边连接,其中 p 是 n 的父节点。
  • 从根路径遍历到每个节点路径唯一。
  • 如果树中的每个节点最多有两个子节点,我们说该树是一个二叉树。

列表型树

myTree = ['a', #root
    ['b', #left subtree
    ['d', [], []],
    ['e', [], []] ],
    ['c', #right subtree
    ['f', [], []],
    [] ]
]
myTree = ['a', ['b', ['d',[],[]], ['e',[],[]] ], ['c', ['f',[],[]], []] ]
print(myTree)
print('left subtree = ', myTree[1])
print('root = ', myTree[0])
print('right subtree = ', myTree[2])

操作列表树

要将左子树添加到树
的根,我们需要在根列表的第二个位置插入一个新的列表。我们必须小心。如果列表已经在
第二个位置有东西,我们需要跟踪它,并沿着树向下把它作为我们添加的列表的左子节点。

def BinaryTree(r):
    return [r, [], []]

def insertLeft(root,newBranch):
    t = root.pop(1)
    if len(t) > 1:
        root.insert(1,[newBranch,t,[]])
    else:
        root.insert(1,[newBranch, [], []])
    return root
def insertRight(root,newBranch):
    t = root.pop(2)
    if len(t) > 1:
        root.insert(2,[newBranch,[],t])
    else:
        root.insert(2,[newBranch,[],[]])
    return root

def getRootVal(root):
    return root[0]

def setRootVal(root,newVal):
    root[0] = newVal

def getLeftChild(root):
    return root[1]

def getRightChild(root):
    return root[2]

节点表示

class BinaryTree:
    def __init__(self,rootObj):
        self.key = rootObj
        self.leftChild = None
        self.rightChild = None

我们必须考虑两种插入情况。 第一种情况的特征没有现有左孩子的节点。当没有左孩子时,只需向树中添加一个节点。 第二种情况的特征在于具有现有左孩子的节点。在第二种情况下,我们插入一个节点并将现有的子节点放到树中的下一个层。

def insertLeft(self,newNode):
    if self.leftChild == None:
        self.leftChild = BinaryTree(newNode)
    else:
        t = BinaryTree(newNode)
        t.leftChild = self.leftChild
        self.leftChild = t
def insertRight(self,newNode):
    if self.rightChild == None:
        self.rightChild = BinaryTree(newNode)
    else:
        t = BinaryTree(newNode)
        t.rightChild = self.rightChild
        self.rightChild = t
def getRightChild(self):
    return self.rightChild

def getLeftChild(self):
    return self.leftChild

def setRootVal(self,obj):
    self.key = obj

def getRootVal(self):
    return self.key

树的遍历

有三种常用的模式来访问树中的所有节点。这些模式之间的差异是每个节点被访问的顺序。我们称这种访问节点方式为“遍历”。我们将看到三种遍历方式称为 前序,中序  和 后序  。

  • 前序 在前序遍历中,我们首先访问根节点,然后递归地做左侧子树的前序遍历,随后是右侧子树的递归前序遍历。
  • 中序 在一个中序遍历中,我们递归地对左子树进行一次遍历,访问根节点,最后递归遍历右子树。
  • 后序 在后序遍历中,我们递归地对左子树和右子树进行后序遍历,然后访问根节点。
def preorder(tree): #前序
    if tree:
        print(tree.getRootVal())
        preorder(tree.getLeftChild())
        preorder(tree.getRightChild())
def postorder(tree):  #后序
    if tree != None:
        postorder(tree.getLeftChild())
        postorder(tree.getRightChild())
        print(tree.getRootVal())
def inorder(tree):  #中序
    if tree != None:
        inorder(tree.getLeftChild())
        print(tree.getRootVal())
        inorder(tree.getRightChild())

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

海人001

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值