zoukankan      html  css  js  c++  java
  • 数据结构与算法(25)——二叉查找树BST

    • 二叉查找树

    性质:比父节点小的key都出现在左子树,比父 节点大的key都出现在右子树。

    ❖按照70,31,93,94,14,23,73的顺序插入

    ❖首先插入的70成为树根 31比70小,

    放到左子节点 93比70大,

    放到右子节点 94比93大,

    放到右子节点 14比31小,

    放到左子节点 23比14大,

    放到其右 73比93小,

    放到其左

    ❖注意:插入顺序不同,生成的BST也不同

    • 代码实现
    class BinarySearchTree:
    
        def __init__(self):
            self.root = None
            self.size = 0
    
        def length(self):
            return self.size
    
        def __len__(self):
            return self.size
    
        def __iter__(self):
            return self.root.__iter__()
    
    class TreeNode:
        def __init__(self, key, val, left=None, right = None, parent = None):
            self.key = key
            self.payload = val #键值
            self.leftChild = left
            self.rightChild = right
            self.parent = parent
    
        def hasLeftChild(self):
            return self.leftChild
    
        def hasRightChild(self):
            return self.rightChild
    
        def isLeftChild(self):
            return self.parent and self.parent.leftChild == self
    
        def isRightChild(self):
            return self.parent and self.parent.rightChild == self
    
        def isRoot(self):
            return not self.parent
    
        def hasAnyChildren(self):
            return self.rightChild or self.leftChild
    
        def hasBothChild(self):
            return self.rightChild and self.leftChild
    
        def replaceNodeData(self,key, value, lc, rc):
            self.key = key
            self.payload = value
            self.leftChild = lc
            self.rightChild = rc
            if self.hasLeftChild():
                self.leftChild.parent = self
            if self.hasRightChild():
                self.rightChild.parent = self
        def put(self, key, val): #插入key构造BST
            if self.root:
                self._put(key, val, self.root)
            else:
                self.root = TreeNode(key, val)
            self.size = self.size + 1
        def _put(self, key, val, currentNode):
            '''
            如果key比currentNode小,那么_put到左子树
            但如果没有左子树,那么key就成为左子节点
            如果key比currentNode大,那么_put到右子树
            但如果没有右子树,那么key就成为右子节点
            '''
            if key < currentNode.key:
                if currentNode.hasLeftChild():
                    self._put(key, val, currentNode.leftChild)
                else:
                    currentNode.leftChild = TreeNode(key, val, parent=currentNode)
            else:
                if currentNode.hasRightChild():
                    self._put(key, val, currentNode.rightChild)
                else:
                    currentNode.rightChild = TreeNode(key, val, parent=currentNode)
        def __setitem__(self, k, v):
            self.put(k ,v)
    
        def get(self, key):
            '''
            在树中找到key所在的节点取到payload
            '''
            if self.root:
                res = self._get(key, self.root)
                if res:
                    return res.payloadd
                else:
                    return None
            else:
                return None
    
        def __get(self, key, currentNode):
            if not currentNode:
                return None
            elif currentNode.key == key:
                return currentNode
            elif key < currentNode.key:
                return self.__get(key, currentNode.leftChild)
            else:
                return self.__get(key, currentNode.rightChild)
    
        def __getitem__(self, key):
            '''
            实现val= myZipTree['PKU']
            '''
            return self.get(key)
    
        def __contains__(self, key):
            '''
            实现'PKU' in myZipTree的归属判断运算符in
            '''
            if self.__get(key, self.root):
                return True
            else:
                return False
        def __iter__(self):
            '''
            实现迭代器
            迭代器函数中用了for迭代,实际上是递归函数
            yield是对每次迭代的返回值 中序遍历的迭代
            :return:
            '''
            if self:
                if self.hasLeftChild():
                    for elem in self.leftChild:
                        yield elem
                yield self.key
                if self.hasRightChild():
                    for elem in self.rightChild:
                        yield elem

    还有BST.delete方法,BST.remove方法 ,比较复杂,这里就不写了。主要思路是要考虑delete是左子节点还是右子节点,然后是否还有左子节点和右子节点。

  • 相关阅读:
    Python保留最后N个元素
    STL算法
    STL迭代器
    STL容器
    C++总结1
    牛客剑指Offer2
    Vue第一天
    UML
    Java继承和组合代码
    Java15后的sealed阻止继承滥用
  • 原文地址:https://www.cnblogs.com/yeshengCqupt/p/13399703.html
Copyright © 2011-2022 走看看