#二叉搜索树 class TreeNode: def __init__(self,key,val,size = 1,color = None,left=None,right=None): #key符号表,val值 color:颜色,红或黑,此处没用,size 以此结点做根的树大小 self.key=key self.val=val self.left = left self.right = right self.color = color self.size = size def __len__(self): return self.size class BST: def __init__(self): self.root = None self.size = 0 def __len__(self): #len()方法 return self.size def __str__(self): #打印BST信息 return 'BST size :(%d)' % self.size __repr__ = __str__ def __contains__(self, key): #in方法 res_val = self._find(self.root,key) if res_val==None: return False return True #构造方法 def __setitem__(self, key, val): return self.insert(key,val) #随机访问方法 def __getitem__(self, key): if isinstance(key, int): return self._find_val(self.root,key) #和数组不同,-1代表key是-1,可以为负,而不是倒数的最后一个 #可以切片 if isinstance(key, slice): res = [] d = 1 if key.start>key.stop: d = -1 for index in range(key.start,key.stop,d): res.append(self._find_val(self.root,index)) return res #数据插入 def insert(self,key,val): if not self.root: self.root = TreeNode(key,val) self.size = 1 return True else: #cur = 0 or 1 #利用python的浅拷贝 cur = self._insert_help(key,val,self.root) self.size += cur if cur==1: return True return False def _insert_help(self,key,val,root): #二分,找不到创建新的,找得到覆盖 if not root: root = TreeNode(key,val) return 1 if key < root.key: if root.left: cur = self._insert_help(key,val,root.left) root.size += cur return cur root.left = TreeNode(key,val) root.size += 1 return 1 if key > root.key: if root.right: cur = self._insert_help(key,val,root.right) root.size += cur return cur root.right = TreeNode(key,val) root.size += 1 return 1 if key == root.key: root.val = val return 0 def pre_print(self,bottom = False): res = [] self._pre_print(self.root,res) print('pre:',res) def _pre_print(self,root,res): if not root: return res.append(root.val) self._pre_print(root.left,res) self._pre_print(root.right,res) return def mid_print(self): res = [] self._mid_print(self.root,res) print('mid:',res) def _mid_print(self,root,res): if not root: return self._mid_print(root.left,res) res.append(root.val) self._mid_print(root.right,res) return def las_print(self): res = [] self._las_print(self.root,res) print('las:',res) def _las_print(self,root,res): if not root: return self._las_print(root.left,res) self._las_print(root.right,res) res.append(root.val) return #find def find_val(self,key): return self._find_val(self.root,key) def _find_val(self,root,key): if not root: return None if key<root.key: return self._find_val(root.left,key) if key>root.key: return self._find_val(root.right,key) if key==root.key: return root.val def find(self,key): return self._find(self.root,key) def _find(self,root,key): if not root: return None if key<root.key: return self._find(root.left,key) if key>root.key: return self._find(root.right,key) if key==root.key: return root #查找树的结点数目 def _size(self,root): if not root: return 0 return len(root) def rank(self,key): if not self.find(key): return 0 return self._rank(self.root,key) def _rank(self,root,key): #key的rank if not root: return 0 if key<root.key: return self._rank(root.left,key) if key==root.key: return 1 + self._size(root.left) if key>root.key: return 1 + self._size(root.left) + self._rank(root.right,key) #最大最小 def max(self,root = None): return self._max(root).val def min(self,root = None): return self._min(root).val def _max(self,root=None): #最大 if root is None: root = self.root while root.right: root = root.right return root def _min(self,root=None): #最小 if root is None: root = self.root while root.left: root = root.left return root #delete #最小结点删除,辅助函数 def _delete_min(self,root): #root不能为空 #root左子树为空,此时最小就是根结点,返回删除根结点后的右子树,即可将根结点删除 if not root.left: #删除,此时size没有发生变换 #self.size-=1 return root.right #左子树不为空,往左子树里面删,返回左子树里面删除最小值后的左子树 root.left = _delete_min(root.left) return root def delete(self,key): #空树 if not self.root: return False res = [False] self.root = self._delete(self.root,key,res) return res[0] def _delete(self,root,key,res=[False]): if not root: return root if key<root.key: root.left = self._delete(root.left,key,res) root.size = self._size(root.left)+self._size(root.right)+1 return root if key>root.key: root.right = self._delete(root.right,key,res) root.size = self._size(root.left)+self._size(root.right)+1 return root #提前减小size,key==root.key,无论哪种情况root都会被删掉 self.size-=1 res[0] = True if not root.left: return root.right if not root.right: return root.left #双方结点都不空 #简单的写法是直接把删除结点的左结点放到删除结点右子树最左叶子结点的左边, #用删除结点的右子树覆盖原先的删除结点,问题是树的高度增高了很多影响性能 #即时删除 #将指向即将被删除的节点的链接保存为t #将x指向后继节点min(t.right) #这一步就是原先结点的位置用所有大于他的右边最小的代替 #右子树删除最小结点,因为最小结点在根点所有很容易删除掉 #将x的左结点设为删除结点t的左结点 t = root root = _min(t.right) root.right = self._delete_min(root.right)#此函数不会将self.size-1 root.left = t.left #原先的root返回时被删掉 return root def get_range(self,key_st,key_en): #左开右闭 if key_en<=key_st or not self.root: return [] res = [] self._get_range(self.root,key_st,key_en,res) return res def _get_range(self,root,st,en,res): if not root: return #中序遍历 if root.key>=st: self._get_range(root.left,st,en,res) if st<=root.key and root.key<en: res.append(root.val) if root.key<en: self._get_range(root.right,st,en,res) return
a = BST() print(a) #初始化 a[2]='b' a[1]='a' a.insert(3,'c'),a.insert(-1,'Y'),a.insert(0,'Z'),a.insert(5,'e'),a.insert(4,'d') print('打印keys,vals:') print([i for i in range(-1,5+1)],['Y','Z','a','b','c','d','e']) print('len功能:%d。in功能\'2 in a\':%s。随机访问功能BST[2]:%s,BST[1:3]:%s'%(len(a),2 in a,a[2],a[1:3])) print('前中后序遍历') a.pre_print(),a.mid_print(),a.las_print()#中序遍历有序 print('find功能,0:%s,1:%s'%(a.find_val(0),a.find_val(1))) print('最小值and最大值:',a.min(),a.max()) print('区域搜索功能[1-4):',a.get_range(1,4)) print('size:',a.root.size,a.root.left.size,a.root.right.size) for i in [-1,0,1,2,3,4,5]: print('rank %s is %s'%(i,a.rank(i))) print('delete key=1',a.delete(1),a[1]) for i in [-1,0,1,2,3,4,5]: print('rank %d is %d'%(i,a.rank(i))) #删除操作 print('删除-1',a.delete(-1)) a.pre_print(),a.mid_print() print('删除-1',a.delete(-1)) a.pre_print(),a.mid_print() print('删除3',a.delete(3)) a.pre_print(),a.mid_print() print('删除3',a.delete(3)) a.pre_print(),a.mid_print()