实现具有重复值的二叉搜索树

时间:2018-12-08 14:12:44

标签: python binary-search-tree

我实现了一个二进制搜索树,该树使用重复的值并将该值存储在一个节点中,并且该节点出现的次数为“ num”。我实现了一个添加节点的函数,如果有重复的节点,则该节点出现的次数将显示在输出中。

我正在尝试创建一个计数函数,该函数对元素在树中出现的次数进行计数。因此例如count(“ code”)应该返回2。

我也在尝试实现删除功能,以删除一个值,但是如果有重复项,则仅应删除该值之一。例如delete(“ code”)应该打印出(code,1),如果“ num”为0,则应删除整个节点。

这是我到目前为止所做的:

class Node:
    def __init__(self,val,l,r):
        self._data = val
        self.num = 1
        self._leftChild = l
        self._rightChild = r


    # prints the node and all its children in a string
    def __str__(self):  
        st = "("+str(self._data)+", "+str(self.num)+") -> ["
        if self._leftChild != None:
            st += str(self._leftChild)
        else: st += "None"
        if self._rightChild != None:
            st += ", "+str(self._rightChild)
        else: st += ", None"
        return st + "]"

    def updateChild(self, oldChild, newChild):
        if self._leftChild == oldChild:
            self._leftChild = newChild
        elif self._rightChild == oldChild:
            self._rightChild = newChild
        else: raise Exception("updateChild error")

class Tree:
    def __init__(self):
        self.root = None
        self.size = 0

    def __str__(self):
        return str(self.root)

    def isEmpty(self):    
        return self.root == None 

    def search(self, val, depth=1):
        if not self.root:
            return 0, 0
        elif self.root._data == val:
            return depth, self.root.num
        elif val < self.root._data:
            return search(self.root._leftChild, val, depth + 1)
        else:
            return search(self.root._rightChild, val, depth + 1

    def add(self, val):
        if self.root == None:
            self.root = Node(val,None,None)

        else:
            pointer = self.root
            while True:
                if val < pointer._data:
                    if pointer._leftChild == None:
                        pointer._leftChild = Node(val,None,None)
                        break
                    pointer = pointer._leftChild
                elif val == pointer._data:
                        pointer.num += 1
                        break
                else:
                    if pointer._rightChild == None:
                        pointer._rightChild = Node(val,None,None)
                        break
                    pointer = pointer._rightChild




    def count(self, val):
        pointer = self.root
        count = 0
        while pointer != None:
            pointer = self.search(pointer,val)
            if pointer != None:
                count += 1
                count = pointer.num
                pointer = pointer._rightChild
        return count




    def delete(self,val):
        if self.root == None:
            return
        if self.root._data == val: 
            return self._removeRoot()
        parentNode = None
        currentNode = self.root
        while currentNode != None and currentNode._data !=val:
            if val < currentNode.data:
                parentNode = currentNode
                currentNode = currentNode._leftChild
            else:
                parentNode = currentNode
                currentNode = currentNode._rightChild
        if currentNode != None:
            return self._removeNode(currentNode,parentNode)

    # removes the node currentNode from the tree altogether
    def _removeNode(self,currentNode,parentNode):
        self.size -= 1
        # 3 cases to consider:
        # 1. the node to be removed is a leaf
        if currentNode._leftChild == currentNode._rightChild == None:
            parentNode.updateChild(currentNode,None)
        # 2.node to be removed has exactly one child
        elif currentNode._leftChild == None or currentNode._rightChild == None:
        if currentNode._leftChild != None:
            parentNode.updateChild(currentNode,currentNode._leftChild)
        else:
            parentNode.updateChild(currentNode,currentNode._rightChild)
    # 3. node to be removed has both children
        else:
            parentMinNode = currentNode
            minNode = currentNode._rightChild
            while minNode._leftChild != None:
                parentMinNode = minNode
                minNode = minNode._leftChild
            parentMinNode.updateChild(minNode,minNode._rightChild)
            parentNode.updateChild(currentNode,minNode)
            minNode._leftChild = currentNode._leftChild
            minNode._rightChild = currentNode._rightChild

    def _removeRoot(self):
        parentNode = Node(None,self.root,None)
        self._removeNode(self.root,parentNode)
        self.root = parentNode._leftChild

这是使用上述类的示例:

t = Tree()
t.add("code"); t.add("pyt"); t.add("hello"); t.add("code")
t.add("java"); t.add("math"); t.add("Comp")


Output: (code, 2) -> [(Comp, 1) -> [None, None], (pyt, 1) -> [(hello, 1) -> [None, (java, 1) -> [None, (math, 1) -> [None, None]]], None]]

之后,当我这样做时:

print(t.count("code"),t.delete("code"),t.count("code"),t.size)

它应该打印:

 2 None 1 6

结果应为:

 (cat, 1) -> [(car, 1) -> [None, (cart, 1) -> [None, None]], (cav, 1) -> [None, (put, 1) ->
[(cs, 1) -> [None, None], None]]]

0 个答案:

没有答案