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是左子节点还是右子节点,然后是否还有左子节点和右子节点。

  • 相关阅读:
    Android 按键消息处理Android 按键消息处理
    objcopy
    SQLite多线程读写实践及常见问题总结
    android动画坐标定义
    Android动画效果translate、scale、alpha、rotate
    Android公共库(缓存 下拉ListView 下载管理Pro 静默安装 root运行 Java公共类)
    Flatten Binary Tree to Linked List
    Distinct Subsequences
    Populating Next Right Pointers in Each Node II
    Populating Next Right Pointers in Each Node
  • 原文地址:https://www.cnblogs.com/yeshengCqupt/p/13399703.html
Copyright © 2011-2022 走看看