BSTree-二叉查找树
作者:互联网
BSTree的全称: Binary Search Tree
【规则】
# 左子节点的值总是小于父节点
# 右子节点的值总是大于父节点
【添加,查找】
# 添加和查找相对简单,按着规则来就可以,比当前值小左边(蓝色),大在右边(黄色)
【删除】
# 首先是要找到要删除的节点,然后再按下面的情况来删除
(a) 待删除节点(蓝色)没有子节点:直接删除
(b) 待删除节点没有左孩子,删除后将它的右孩子移过去。如图中的20,30,19都是没有左孩子的节点
# 3个节点分别删除后
(c) 待删除节点没有右孩子,删除后将它的左孩子移过去。
(d) 待删除节点左右孩子都有,在待删除节点的右子树中找到值最小的节点,用它的值替换待删除节点的值,然后删除那个最小的节点。
# 11为待删除节点,先在右子树找到最小的节点12,12值替换11,最后删除节点12(使用规则b)
# 11为待删除节点,先在右子树找到最小的节点12,12值替换11,最后删除节点12(使用规则a)
# 其他的一些情况:待删除节点的右子树都是右孩子
# 待删除的节点在根节点
local Node = {} Node.__cname = "util.BSTree.Node" Node.__index = Node function Node.new(v) local obj = {} setmetatable(obj, Node) obj:ctor(v) return obj end function Node:ctor(v) self.value = v self.left = nil self.right = nil end
local BSTree = {} BSTree.__cname = "util.BSTree" BSTree.__index = BSTree function BSTree.new(cmpFunc) local obj = {} setmetatable(obj, BSTree) obj:ctor(cmpFunc) return obj end function BSTree:ctor(cmpFunc) self.cmpFunc = cmpFunc self.count = 0 self.root = nil end function BSTree:Clear() self.count = 0 self.root = nil end function BSTree:GetCount() return self.count end function BSTree:Add(v) local newNode = Node.new(v) if nil == self.root then self.root = newNode self.count = self.count + 1 return end local node = self.root while nil ~= node do local cmpResult = self.cmpFunc(v, node.value) if cmpResult < 0 then --小: 在左子树添加 if nil == node.left then node.left = newNode self.count = self.count + 1 break else node = node.left end elseif cmpResult > 0 then --大: 在右子树添加 if nil == node.right then node.right = newNode self.count = self.count + 1 break else node = node.right end else print(tostring(v), "have exist, ignore") end end end function BSTree:Contains(v) if self.count < 1 then return false end local node = self.root while nil ~= node do local cmpResult = self.cmpFunc(v, node.value) if cmpResult < 0 then node = node.left elseif cmpResult > 0 then node = node.right else return true end end return false end function BSTree:Remove(v) if self.count < 1 then return false end local parent = nil local node = self.root while nil ~= node do local cmpResult = self.cmpFunc(v, node.value) if cmpResult < 0 then parent = node node = node.left elseif cmpResult > 0 then parent = node node = node.right else self:_DelNode(node, parent) self.count = self.count - 1 return true end end return false end function BSTree:_DelNode(delNode, delNodeParent) if nil == delNode.left and nil == delNode.right then --删除节点没有子节点, 直接删除(断开与parent的关系) if delNode == self.root then self.root = nil elseif delNodeParent.left == delNode then delNodeParent.left = nil elseif delNodeParent.right == delNode then delNodeParent.right = nil else print("error") end elseif nil == delNode.left then --删除节点只有右子节点, 断开与parent的关系, parent子节点直接指向那个右子节点 if delNode == self.root then self.root = delNode.right elseif delNodeParent.left == delNode then delNodeParent.left = delNode.right elseif delNodeParent.right == delNode then delNodeParent.right = delNode.right else print("error") end delNode.right = nil --断开节点关系 elseif nil == delNode.right then --删除节点只有左子节点, 断开与parent的关系, parent子节点直接指向那个左子节点 if delNode == self.root then self.root = delNode.left elseif delNodeParent.left == delNode then delNodeParent.left = delNode.left elseif delNodeParent.right == delNode then delNodeParent.right = delNode.left else print("error") end delNode.left = nil --断开节点关系 else --左右子节点都有, 右子树中找一个最小的节点替换到删除节点处 local replaceNode, replaceNodeParent = self:_FindReplaceNode(delNode) delNode.value = replaceNode.value self:_DelNode(replaceNode, replaceNodeParent) end end function BSTree:_FindReplaceNode(delNode) local parent = delNode local node = delNode.right while nil ~= node do if nil ~= node.left then parent = node node = node.left else return node, parent end end print("error") end function BSTree:__tostring() if self.count < 1 then return "" end local strTb = {} local queue = {} table.insert(queue, self.root) while #queue > 0 do local node = queue[1] table.remove(queue, 1) table.insert(strTb, tostring(node.value)) if nil ~= node.left then table.insert(queue, node.left) end if nil ~= node.right then table.insert(queue, node.right) end end return table.concat(strTb, ",") end return BSTree
【参考】
【数据结构】——搜索二叉树的插入,查找和删除(递归&非递归) - 龙跃十二 - 博客园 (cnblogs.com)
搜索算法—二叉搜索树 - MichaelCen - 博客园 (cnblogs.com), 讲的非常全,Floor, Ceil, Rank都讲到了
标签:node,end,nil,delNode,self,二叉,查找,BSTree,节点 来源: https://www.cnblogs.com/sailJs/p/16049868.html