在BST中查找小于给定元素的元素数

时间:2013-11-13 04:43:14

标签: python binary-search-tree

我一直在努力解决这个问题,而且我是BST的Python初学者,所以我很感激一些帮助。我正在动态地将(未排序的)数组中的元素添加到BST中。那部分很好,我知道该怎么做。下一步,用我目前的技能证明是不可能的。当我向树中添加元素时,我需要能够找到树中任何元素的当前等级。我知道这个问题有微妙之处,所以我需要帮助才能至少找到BST中给定节点下面的节点数。例如,在这种情况下,节点15下面有节点10,5和13,所以函数将返回3.这是我现有的代码[这是破解编码访谈的问题,第11章]

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):
        self.root = None

    def addNode(self, data):
        return Node(data)

    def insert(self, root, data):
        if root == None:
            return self.addNode(data)
        else:
            if data <= root.data:
                root.numLeftChildren+=1
                root.left = self.insert(root.left, data)
            else:
                root.numRightChildren+=1
                root.right = self.insert(root.right, data)
            return root 
    def getRankOfNumber(self,root,x):
        if root==None:
            return 0
        else:
            if x>root.data :
                return self.getRankOfNumber(root.right,x)+root.numLeftChildren+1
            elif root.data==x:
                return root.numLeftChildren
            else:
                return self.getRankOfNumber(root.left,x)   
BTree=BSTree()
root=BTree.addNode(20)
BTree.insert(root,25)
BTree.insert(root,15)
BTree.insert(root,10)
BTree.insert(root,5)
BTree.insert(root,13)
BTree.insert(root,23)

4 个答案:

答案 0 :(得分:1)

您可以修改BST以包含每个节点下的节点数。

或者你可以迭代传统的BST从最小到最大,随着你的计算,当你找到一个具有所需值的节点时停止计数。

答案 1 :(得分:1)

你可以采用这种方法:

1. Have 2 more fields in each node numLeftChildren and numRightChildren.
2. Initialize both of them to 0 when you create a new node.
3. At the time of insertion, you make a comparison if the newly added node's
key is less than root's key than you increment, root's numLeftChildren and
call recursion on root's left child with the new node.
4. Do Same thing if new node's key is greater than root's key.

现在,回到原来的问题,您必须找出左子树中的子项数。只需在O(logN)时间找出该节点,然后打印 numLeftChildren

时间复杂度:O(logN)

PS:我添加了另一个字段numRightChildren,如果你总是想知道左子树中的节点数,你可以删除它。

答案 2 :(得分:0)

您可以仅使用Node类的实例来简化代码,因为您的BSTree实例始终在根节点上运行。另一个优化可能是不将重复的值表示为单独的节点,而是使用密钥出现次数的计数器:

class Node:
    def __init__(self, data):
        self.data = data
        self.left = None
        self.right = None
        self.num_left_children = 0
        self.occurrences = 1

    def insert(self, data):
        if data < self.data:
            if self.left is None:
                self.left = Node(data)
            else:
                self.left.insert(data)
            self.num_left_children += 1
        elif data > self.data:
            if self.right is None:
                self.right = Node(data)
            else:
                self.right.insert(data)
        else:
            self.occurrences += 1

    def get_rank(self, data):
        if data < self.data:
            return self.left.get_rank(data)
        elif data > self.data:
            return (self.occurrences + self.num_left_children +
                    self.right.get_rank(data))
        else:
            return self.num_left_children

演示:

root = Node(20)
root.insert(25)
root.insert(15)
root.insert(10)
root.insert(10)
root.insert(5)
root.insert(13)
root.insert(23)

print(root.get_rank(15))  # 4

答案 3 :(得分:-1)

您可以使用以下函数查找树中的节点数(包括根)。

def countNodes(self, root):
    if root == None:
        return 0
    else
        return (1 + countNodes(root.left) + countNodes(root.right));

要查找位于root以下的节点数,请从函数返回的值中减去1。我认为这将有助于您解决问题。

您的代码如下:

类节点: msgstr“”“节点的文档字符串”“” def init (自我,数据):     self.data =数据     self.left =无     self.right =无     self.depth = 0

班级BSTree:     def init (个体经营):         self.root =无

def addNode(self, data):
    return Node(data)

def insert(self, root, data):
    if root == None:
        return self.addNode(data)
    else:
        if data <= root.data:
            root.left = self.insert(root.left, data)
        else:
            root.right = self.insert(root.right, data)
        return root

B树= BSTree() 根= BTree.addNode(20) BTree.insert(根,25) BTree.insert(根,15) BTree.insert(根,10) BTree.insert(根,5) BTree.insert(根,13) BTree.insert(根,23) BTree.insert(根,23)

numLeft = countNodes(root-&gt; left); numRight = countNodes(root-&gt; right); numChildren = numLeft + numRight;