在二叉树中找到一个节点的后继节点

在二叉树中找到一个节点的后继节点

题目

假设二叉搜索树节点带有父节点指针:

class TreeNode():
    def __init__(self, val):
        self.val = val
        self.left = None
        self.right = None
        self.parent = None

给定二叉搜索树上一个节点node,返回node的后继节点

BST

class BST():
    def __init__(self, root=None):
        self.root = root

    def insert_recursive(self, val):
        def recursive(node, val):
            if not node:
                return TreeNode(val)

            if val < node.val:
                node.left = recursive(node.left, val)
                node.left.parent = node
            elif val > node.val:
                node.right = recursive(node.right, val)
                node.right.parent = node

            return node

        self.root = recursive(self.root, val)

    def inorder_traversal_recursive(self):
        def recursive(node):
            if node:
                recursive(node.left)
                result.append(node.val)
                recursive(node.right)

        result = []
        recursive(self.root)
        return result

    def preorder_traversal_recursive(self):
        def recursive(node):
            if node:
                result.append(node.val)
                recursive(node.left)
                recursive(node.right)

        result = []
        recursive(self.root)
        return result

    def postorder_traversal_recursive(self):
        def recursive(node):
            if node:
                recursive(node.left)
                recursive(node.right)
                result.append(node.val)

        result = []
        recursive(self.root)
        return result

思路

  • 如果node有右子树,后继节点为右子树上最左边的节点
  • 如果node没有右子树,假设node的父节点为p,如果node是p的左孩子,那么p就是node的后继节点;否则如果node是p的右孩子,则向上找,找到是子节点是父节点左孩子的节点。

实现

    def get_left_most_node(self, node):
        if node is None:
            return node

        while node.left is not None:
            node = node.left

        return node

    def successor(self, node):
        if node is None:
            return node

        if node.right is not None:
            return self.get_left_most_node(node.right)
        else:
            parent = node.parent
            while parent is not None and parent.left != node:
                node = parent
                parent = node.parent
            return parent

测试

import unittest
import random
import bst as bst
import operator


class FindSuccessorTestCase(unittest.TestCase):
    def test_find_successor_simple(self):
        count = 10
        data = [i for i in range(count)]
        random.shuffle(data)

        tree = bst.BST()
        for d in data:
            tree.insert_recursive(d)

        inorder = tree.inorder_traversal_recursive()
        node = tree.get_left_node(tree.root)
        successors = []
        while node:
            successors.append(node.val)
            node = tree.successor(node)

        self.assertTrue(operator.eq(inorder, successors))

    def test_find_successor(self):
        test_count = 100
        count = 100

        for _ in range(test_count):
            data = [i for i in range(count)]
            random.shuffle(data)
            tree = bst.BST()
            for d in data:
                tree.insert_recursive(d)

            inorder = tree.inorder_traversal_recursive()
            node = tree.get_left_node(tree.root)
            successors = []
            while node:
                successors.append(node.val)
                node = tree.successor(node)

            self.assertTrue(operator.eq(inorder, successors))

结果

➜  17_find_successor git:(master) ✗ python -m unittest test_find_successor.py
..
----------------------------------------------------------------------
Ran 2 tests in 0.038s

OK

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值