• 6.5.节点表示

    6.5.节点表示

    我们的第二种表示树的方法使用节点和引用。在这种情况下,我们将定义一个具有根值属性的类,以及左和右子树。 由于这个表示更接近于面向对象的编程范例,我们将继续使用这个表示法用于本章的剩余部分。

    使用节点和引用,我们认为树结构类似于 Figure 2 所示。

    6.5.节点表示.figure2

    Figure 2

    我们将从节点和引用方法的一个简单的类定义开始,如 Listing 4 所示。要记住这个表示重要的事情是 leftright 的属性将成为对 BinaryTree 类的其他实例的引用。 例如,当我们在树中插入一个新的左子节点时,我们创建另一个 BinaryTree 实例,并在根节点中修改self.leftChild 来引用新树节点。

    1. class BinaryTree:
    2. def __init__(self,rootObj):
    3. self.key = rootObj
    4. self.leftChild = None
    5. self.rightChild = None

    Listing 4

    请注意,在 Listing 4 中,构造函数希望获取某种对象存储在根中。 就像你可以在列表中存储任何你喜欢的对象一样,树的根对象可以是对任何对象的引用。 对于我们的先前示例,我们将存储节点的名称作为根值。使用节点和引用来表示 Figure 2 中的树,我们将创建 BinaryTree 类的六个实例。

    接下来,我们来看看需要构建超出根节点的树的函数。要向树中添加一个左子树,我们将创建一个新的二叉树对象,并设置根的左边属性来引用这个新对象。 insertLeft 的代码如 Listing 5所示。

    1. def insertLeft(self,newNode):
    2. if self.leftChild == None:
    3. self.leftChild = BinaryTree(newNode)
    4. else:
    5. t = BinaryTree(newNode)
    6. t.leftChild = self.leftChild
    7. self.leftChild = t

    Listing 5

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

    insertRight 的代码必须考虑一组对称的情况。没有右孩子,或者我们在根和现有右孩子之间插入节点。 插入代码如 Listing 6 所示。

    1. def insertRight(self,newNode):
    2. if self.rightChild == None:
    3. self.rightChild = BinaryTree(newNode)
    4. else:
    5. t = BinaryTree(newNode)
    6. t.rightChild = self.rightChild
    7. self.rightChild = t

    Listing 6

    为了完成一个简单二叉树数据结构的定义,我们将实现获取 左和右孩子(见 Listing 7 )以及根值的方法。

    1. def getRightChild(self):
    2. return self.rightChild
    3. def getLeftChild(self):
    4. return self.leftChild
    5. def setRootVal(self,obj):
    6. self.key = obj
    7. def getRootVal(self):
    8. return self.key

    Listing 7

    现在我们有了创建和操作二叉树的所有部分,让我们使用它们来检查结构。 我们使用节点 a 作为根的简单树,并将节点 b 和 c 添加为子节点。 ActiveCode 1 创建树并查看存储在 key,left 和 right 中的一些值。注意,根的左和右孩子本身是 BinaryTree 类的不同实例。正如我们在对树的原始递归定义中所说的,这允许我们将二叉树的任何子项视为二叉树本身。

    1. class BinaryTree:
    2. def __init__(self,rootObj):
    3. self.key = rootObj
    4. self.leftChild = None
    5. self.rightChild = None
    6. def insertLeft(self,newNode):
    7. if self.leftChild == None:
    8. self.leftChild = BinaryTree(newNode)
    9. else:
    10. t = BinaryTree(newNode)
    11. t.leftChild = self.leftChild
    12. self.leftChild = t
    13. def insertRight(self,newNode):
    14. if self.rightChild == None:
    15. self.rightChild = BinaryTree(newNode)
    16. else:
    17. t = BinaryTree(newNode)
    18. t.rightChild = self.rightChild
    19. self.rightChild = t
    20. def getRightChild(self):
    21. return self.rightChild
    22. def getLeftChild(self):
    23. return self.leftChild
    24. def setRootVal(self,obj):
    25. self.key = obj
    26. def getRootVal(self):
    27. return self.key
    28. r = BinaryTree('a')
    29. print(r.getRootVal())
    30. print(r.getLeftChild())
    31. r.insertLeft('b')
    32. print(r.getLeftChild())
    33. print(r.getLeftChild().getRootVal())
    34. r.insertRight('c')
    35. print(r.getRightChild())
    36. print(r.getRightChild().getRootVal())
    37. r.getRightChild().setRootVal('hello')
    38. print(r.getRightChild().getRootVal())