简体   繁体   English

如何在BST中找到第k个最小的节点? (重访)

[英]How to find the kth smallest node in BST? (revisited)

I have asked a similar question yesterday but I reached a different solution from the one posted in the original question sO I am reposting with new code. 昨天我问了一个类似的问题,但是我得到的解决方案与原始问题中发布的解决方案不同,因此我将使用新代码重新发布。 I am not keeping track of number of right and left children of each node. 我没有跟踪每个节点的左右子节点数。 The code works fine for some cases, but for the case of of finding 6th smalest element, it fails. 该代码在某些情况下可以正常工作,但是对于找到第6个最小元素的情况,它将失败。 The problem is that I somehow need to carry the number of children down the tree. 问题是我不知何故需要把孩子的数目带到树上。 For example, for node 5, I need to cary over rank of node 4 and I am not able to do that. 例如,对于节点5,我需要关心节点4的等级,而我无法做到这一点。

This is not a homework, I am trying to prepare for interview and this is one of the classical questions and I can't solve it. 这不是家庭作业,我正在尝试准备面试,这是经典问题之一,我无法解决。

class Node:
    """docstring for Node"""
    def __init__(self, data):
        self.data = data
        self.left = None
        self.right = None
        self.numLeftChildren = 0
        self.numRightChildren = 0


class BSTree:
    def __init__(self):
        # initializes the root member
        self.root = None

    def addNode(self, data):
        # creates a new node and returns it
        return Node(data)

    def insert(self, root, data):
        # inserts a new data
        if root == None:
            # it there isn't any data
            # adds it and returns
            return self.addNode(data)
        else:
            # enters into the tree
            if data <= root.data:
                root.numLeftChildren += 1
                # if the data is less than the stored one
                # goes into the left-sub-tree
                root.left = self.insert(root.left, data)
            else:
                # processes the right-sub-tree
                root.numRightChildren += 1
                root.right = self.insert(root.right, data)
            return root

    def getRankOfNumber(self, root, x, rank):
        if root == None:
            return 0
        if rank == x:
            return root.data
        else:
            if x > rank:
                return self.getRankOfNumber(root.right, x, rank+1+root.right.numLeftChildren)
            if x <= rank:
                return self.getRankOfNumber(root.left, x, root.left.numLeftChildren+1)


# main
btree = BSTree()
root = btree.addNode(13)
btree.insert(root, 3)
btree.insert(root, 14)
btree.insert(root, 1)
btree.insert(root, 4)
btree.insert(root, 18)
btree.insert(root, 2)
btree.insert(root, 12)
btree.insert(root, 10)
btree.insert(root, 5)
btree.insert(root, 11)
btree.insert(root, 8)
btree.insert(root, 7)
btree.insert(root, 9)
btree.insert(root, 6)

print btree.getRankOfNumber(root, 8, rank=root.numLeftChildren+1)

You have the rank of a node. 您具有节点的等级。 You need to find the rank of its left or right child. 您需要找到其左或右子级的等级。 Well, how many nodes are between the node and its child? 那么,该节点与其子节点之间有多少个节点?

     a
    / \
   /   \
  b     c
 / \   / \
W   X Y   Z

Here's an example BST. 这是一个BST示例。 Lowercase letters are nodes; 小写字母是节点; uppercase are subtrees. 大写字母是子树。 The number of nodes between a and b is the number of nodes in X . ab之间的节点数是X的节点数。 The number of nodes between a and c is the number of nodes in Y . ac之间的节点数是Y的节点数。 Thus, you can compute the rank of b or c from the rank of a and the size of X or Y . 因此,可以计算的等级bc从秩a的尺寸和XY

rank(b) == rank(a) - size(X) - 1
rank(c) == rank(a) + size(Y) + 1

You had the c formula, but the wrong b formula. 您使用了c公式,但是使用了错误的b公式。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM