github.com/qiuhoude/go-web@v0.0.0-20220223060959-ab545e78f20d/algorithm/datastructures/tree/bst/binarySearchTree.go (about)

     1  package bst
     2  
     3  import (
     4  	"container/list"
     5  	"fmt"
     6  	"github.com/qiuhoude/go-web/algorithm/datastructures/stack"
     7  	"strings"
     8  )
     9  
    10  // 可比较的接口
    11  type Comparable interface {
    12  	// 比较大小 相等返回0 , 当前这个数小返回负数 ,当前数大返回正数
    13  	CompareTo(o Comparable) int
    14  }
    15  
    16  type node struct {
    17  	val         Comparable // 包含的值
    18  	left, right *node      // 左右节点
    19  	size        int        // 子节点的数量
    20  	depth       int        // 该节点的深度
    21  }
    22  
    23  type BST struct {
    24  	root *node // 根节点
    25  }
    26  
    27  func (t *BST) Size() int {
    28  	if t.root == nil {
    29  		return 0
    30  	}
    31  	return t.root.size
    32  }
    33  
    34  func (t *BST) IsEmpty() bool {
    35  	return t.Size() == 0
    36  }
    37  
    38  // 向二分搜索树中添加新的元素
    39  func (t *BST) Add(e Comparable) {
    40  	t.root, _ = add(t.root, e, 0)
    41  }
    42  
    43  // 第二bool值表示true表示添加成功, false表示添加失败
    44  func add(n *node, e Comparable, depth int) (*node, bool) {
    45  	if n == nil {
    46  		rn := &node{val: e, depth: depth}
    47  		rn.size++
    48  		return rn, true
    49  	}
    50  	var addSuc bool
    51  	if e.CompareTo(n.val) < 0 { // e值小,挂载到左边
    52  		n.left, addSuc = add(n.left, e, depth+1)
    53  	} else if e.CompareTo(n.val) > 0 { // e值大,挂载到右边
    54  		n.right, addSuc = add(n.right, e, depth+1)
    55  	} else { //相等的情况先不做处理
    56  	}
    57  	if addSuc { // 添加成功让 size++
    58  		n.size++
    59  	}
    60  	return n, addSuc
    61  }
    62  
    63  // 查看是否包含此元素e
    64  func (t *BST) Contains(e Comparable) bool {
    65  	return contains(t.root, e)
    66  }
    67  
    68  // 看以node为根的二分搜索树中是否包含元素e, 递归算法
    69  func contains(n *node, e Comparable) bool {
    70  	if n == nil {
    71  		return false
    72  	}
    73  	if e.CompareTo(n.val) < 0 {
    74  		return contains(n.left, e)
    75  	} else if e.CompareTo(n.val) > 0 {
    76  		return contains(n.right, e)
    77  	} else { //e.CompareTo(n.val) == 0
    78  		return true
    79  	}
    80  }
    81  
    82  type TraverseFunc func(e Comparable)
    83  
    84  // 前序遍历,最常见的变量方式 preOrder traverse
    85  func (t *BST) PreOrder(f TraverseFunc) {
    86  	preOrder(t.root, f)
    87  }
    88  
    89  func preOrder(n *node, f TraverseFunc) {
    90  	if n == nil {
    91  		return
    92  	}
    93  	f(n.val)
    94  	preOrder(n.left, f)
    95  	preOrder(n.right, f)
    96  }
    97  
    98  // 中序遍历,是从小到大
    99  func (t *BST) InOrder(f TraverseFunc) {
   100  	inOrder(t.root, f)
   101  }
   102  
   103  func inOrder(n *node, f TraverseFunc) {
   104  	if n == nil {
   105  		return
   106  	}
   107  	inOrder(n.left, f)
   108  	f(n.val)
   109  	inOrder(n.right, f)
   110  }
   111  
   112  // 后续序遍历
   113  func (t *BST) PostOrder(f TraverseFunc) {
   114  	postOrder(t.root, f)
   115  }
   116  
   117  func postOrder(n *node, f TraverseFunc) {
   118  	if n == nil {
   119  		return
   120  	}
   121  	postOrder(n.left, f)
   122  	postOrder(n.right, f)
   123  	f(n.val)
   124  }
   125  
   126  //前序遍历 非递归的方式 NR=non recursion
   127  func (t *BST) PreOrderNR(f TraverseFunc) {
   128  	n := t.root
   129  	if n == nil {
   130  		return
   131  	}
   132  	s := stack.New()
   133  	s.Push(n)
   134  	for !s.IsEmpty() {
   135  		tn, _ := s.Pop().(*node)
   136  		f(tn.val)
   137  		if tn.right != nil {
   138  			s.Push(tn.right)
   139  		}
   140  		if tn.left != nil {
   141  			s.Push(tn.left)
   142  		}
   143  	}
   144  }
   145  
   146  //前序遍历 非递归的方式2
   147  func (t *BST) PreOrderNR2(f TraverseFunc) {
   148  	n := t.root
   149  	if n == nil {
   150  		return
   151  	}
   152  	s := stack.New()
   153  	for n != nil || !s.IsEmpty() {
   154  		for n != nil {
   155  			f(n.val)
   156  			s.Push(n)
   157  			n = n.left
   158  		}
   159  		n = s.Pop().(*node)
   160  		n = n.left
   161  	}
   162  }
   163  
   164  // 中序遍历非递归
   165  func (t *BST) InOrderNR(f TraverseFunc) {
   166  	n := t.root
   167  	if n == nil {
   168  		return
   169  	}
   170  	s := stack.New()
   171  	for n != nil || !s.IsEmpty() {
   172  		for n != nil { // 找到最小的
   173  			s.Push(n)
   174  			n = n.left
   175  		}
   176  		n, _ = s.Pop().(*node)
   177  		f(n.val)
   178  		n = n.right
   179  	}
   180  }
   181  
   182  //中序遍历非递归的第2种方式
   183  func (t *BST) InOrderNR2(f TraverseFunc) {
   184  	n := t.root
   185  	if n == nil {
   186  		return
   187  	}
   188  	s := stack.New()
   189  	for n != nil || !s.IsEmpty() {
   190  		if n != nil {
   191  			s.Push(n)
   192  			n = n.left
   193  		} else {
   194  			n = s.Pop().(*node)
   195  			f(n.val)
   196  			n = n.right
   197  		}
   198  	}
   199  }
   200  
   201  // 后续遍历 非递归方式
   202  func (t *BST) PostOrderNR(f TraverseFunc) {
   203  	cur := t.root
   204  	if cur == nil {
   205  		return
   206  	}
   207  	s := stack.New()
   208  	var pre *node //Using a pre pointer to record the last visted node
   209  	for cur != nil || !s.IsEmpty() {
   210  		for cur != nil {
   211  			s.Push(cur)
   212  			cur = cur.left
   213  		}
   214  		cur, _ = s.Pop().(*node)
   215  		if cur.right == nil || pre == cur.right {
   216  			f(cur.val)
   217  			pre = cur
   218  			cur = nil
   219  		} else {
   220  			s.Push(cur)
   221  			cur = cur.right
   222  		}
   223  	}
   224  }
   225  
   226  // Morris 方式进行遍历搜索树,不借用占 只用普通的变量
   227  func (t *BST) PreOrderMorris(f TraverseFunc) {
   228  	cur := t.root
   229  	if cur == nil {
   230  		return
   231  	}
   232  	for cur != nil {
   233  		if cur.left == nil {
   234  			f(cur.val)
   235  			cur = cur.right
   236  		} else {
   237  			prev := cur.left
   238  			for prev.right != nil && prev.right != cur {
   239  				prev = prev.right
   240  			}
   241  			if prev.right == nil {
   242  				f(cur.val)
   243  				prev.right = cur
   244  				cur = cur.left
   245  			} else {
   246  				prev.right = nil
   247  				cur = cur.right
   248  			}
   249  		}
   250  	}
   251  }
   252  
   253  func (t *BST) InOrderMorris(f TraverseFunc) {
   254  	cur := t.root
   255  	if cur == nil {
   256  		return
   257  	}
   258  	for cur != nil {
   259  		if cur.left == nil {
   260  			f(cur.val)
   261  			cur = cur.right
   262  		} else {
   263  			prev := cur.left
   264  			for prev.right != nil && prev.right != cur {
   265  				prev = prev.right
   266  			}
   267  			if prev.right == nil {
   268  				prev.right = cur
   269  				cur = cur.left
   270  			} else {
   271  				prev.right = nil
   272  				f(cur.val)
   273  				cur = cur.right
   274  			}
   275  		}
   276  	}
   277  }
   278  
   279  // 二分搜索树的层序遍历,也是广度遍历,借助队列的结构遍历
   280  func (t *BST) LevelOrder(f TraverseFunc) {
   281  	if t.root == nil {
   282  		return
   283  	}
   284  	l := list.New()
   285  	l.PushBack(t.root)
   286  	for l.Len() != 0 {
   287  		n, _ := l.Remove(l.Front()).(*node)
   288  		f(n.val)
   289  		if n.left != nil {
   290  			l.PushBack(n.left)
   291  		}
   292  		if n.right != nil {
   293  			l.PushBack(n.right)
   294  		}
   295  	}
   296  }
   297  
   298  // 该树的最大深度
   299  func (t *BST) MaxDepth() int {
   300  	return maxDepth(t.root)
   301  
   302  	//if t.root == nil {
   303  	//	return 0
   304  	//}
   305  	//maxD := 0
   306  	//calcDepth(t.root, 0, &maxD)
   307  	//return maxD
   308  
   309  }
   310  func calcDepth(n *node, depth int, maxDepth *int) {
   311  	if n == nil {
   312  		return
   313  	}
   314  	if *maxDepth < depth+1 {
   315  		*maxDepth = depth + 1
   316  	}
   317  	calcDepth(n.left, depth+1, maxDepth)
   318  	calcDepth(n.right, depth+1, maxDepth)
   319  }
   320  
   321  func maxDepth(n *node) int {
   322  	if n == nil {
   323  		return 0
   324  	}
   325  	// 可用理解为是后序遍历
   326  	// 在跟父点处比较大小
   327  	leftDepth := maxDepth(n.left)
   328  	rightDepth := maxDepth(n.right)
   329  	return max(leftDepth, rightDepth) + 1
   330  }
   331  
   332  func minDepth(n *node) int {
   333  	if n == nil {
   334  		return 0
   335  	}
   336  	if n.left == nil { // 若左子树为空,则右子树的深度为为该节点的深度
   337  		return minDepth(n.right) + 1
   338  	}
   339  	if n.right == nil {
   340  		return minDepth(n.left) + 1
   341  	}
   342  	leftDepth := minDepth(n.left)
   343  	rightDepth := minDepth(n.right)
   344  	return min(leftDepth, rightDepth) + 1
   345  }
   346  
   347  func min(a, b int) int {
   348  	if a > b {
   349  		return b
   350  	} else {
   351  		return a
   352  	}
   353  }
   354  
   355  func max(a, b int) int {
   356  	if a > b {
   357  		return a
   358  	} else {
   359  		return b
   360  	}
   361  }
   362  
   363  // 寻找二分搜索树的最小元素
   364  func (t *BST) Minimum() Comparable {
   365  	if t.root == nil {
   366  		return nil
   367  	}
   368  	return minimum(t.root).val
   369  }
   370  
   371  func minimum(n *node) *node {
   372  	if n.left == nil {
   373  		return n
   374  	}
   375  	return minimum(n.left)
   376  }
   377  
   378  // 寻找二分搜索树的最小元素 非递归方式
   379  func (t *BST) MinimumNR() Comparable {
   380  	if t.root == nil {
   381  		return nil
   382  	}
   383  	tn := t.root
   384  	for {
   385  		if tn.left == nil {
   386  			break
   387  		}
   388  		tn = tn.left
   389  	}
   390  	return tn.val
   391  }
   392  
   393  // 寻找二分搜索树的最大元素
   394  func (t *BST) Maximum() Comparable {
   395  	if t.root == nil {
   396  		return nil
   397  	}
   398  	return maximum(t.root).val
   399  }
   400  
   401  func maximum(n *node) *node {
   402  	if n.right == nil {
   403  		return n
   404  	}
   405  	return maximum(n.right)
   406  }
   407  
   408  func (t *BST) MaximumNR() Comparable {
   409  	if t.root == nil {
   410  		return nil
   411  	}
   412  	tn := t.root
   413  	for {
   414  		if tn.right == nil {
   415  			break
   416  		}
   417  		tn = tn.right
   418  	}
   419  	return tn.val
   420  }
   421  
   422  // 从二分搜索树中删除最小值所在节点, 返回最小值
   423  func (t *BST) RemoveMin() Comparable {
   424  	if t.root == nil {
   425  		return nil
   426  	}
   427  	ret := minimum(t.root)
   428  	t.root = removeMin(t.root)
   429  	return ret.val
   430  }
   431  
   432  // 删除掉以node为根的二分搜索树中的最小节点
   433  // 返回删除节点后新的二分搜索树的根 和 是否删除成功
   434  func removeMin(n *node) *node {
   435  	if n.left == nil {
   436  		// 将要删除的右节点挂载父节点上,通过返回值返给服节点
   437  		tn := n.right
   438  		n.right = nil // 置空 gc回收
   439  		opDepth(tn, -1)
   440  		return tn
   441  	}
   442  	n.left = removeMin(n.left)
   443  	n.size--
   444  	return n
   445  }
   446  
   447  // 对节点下面的所有节点进行操作
   448  func opDepth(n *node, op int) {
   449  	if n == nil {
   450  		return
   451  	}
   452  	n.depth = n.depth + op
   453  	opDepth(n.left, op)
   454  	opDepth(n.right, op)
   455  }
   456  
   457  // 从二分搜索树中删除最大值所在节点
   458  func (t *BST) RemoveMax() Comparable {
   459  	if t.root == nil {
   460  		return nil
   461  	}
   462  	ret := maximum(t.root)
   463  	t.root = removeMax(t.root)
   464  	return ret.val
   465  }
   466  
   467  func removeMax(n *node) *node {
   468  	if n.right == nil {
   469  		tn := n.left
   470  		n.left = nil
   471  		opDepth(tn, -1)
   472  		return tn
   473  	}
   474  	n.right = removeMax(n.right)
   475  	n.size--
   476  	return n
   477  }
   478  
   479  // 移除指定元素,返回true表示移除成功
   480  func (t *BST) Remove(c Comparable) bool {
   481  	if !t.Contains(c) { // 不存在删除失败
   482  		return false
   483  	}
   484  	n := remove(t.root, c)
   485  	t.root = n
   486  	return true
   487  }
   488  
   489  // 移除对应元素,返回跟节点
   490  func remove(n *node, c Comparable) *node {
   491  	if n == nil {
   492  		return nil
   493  	}
   494  	if c.CompareTo(n.val) < 0 {
   495  		n.left = remove(n.left, c)
   496  		if n.left != nil {
   497  			n.size--
   498  		}
   499  		return n
   500  	} else if c.CompareTo(n.val) > 0 {
   501  		n.right = remove(n.right, c)
   502  		if n.right != nil {
   503  			n.size--
   504  		}
   505  		return n
   506  	} else { //相等,进行移除
   507  		// 以下分几种情况
   508  
   509  		// 1. 待删除节点左子树为空的情况
   510  		if n.left == nil { // 将右子树的数据反给上层
   511  			tn := n.right
   512  			n.left = nil
   513  			opDepth(tn, -1)
   514  			return tn
   515  		}
   516  		// 2. 待删除节点右子树为空的情况
   517  		if n.right == nil {
   518  			tn := n.left
   519  			n.left = nil
   520  			opDepth(tn, -1)
   521  			return tn
   522  		}
   523  
   524  		// 3. 左右都有数据,
   525  		// 找到比待删除节点大的最小节点, 即待删除节点右子树的最小节点
   526  		// 用这个节点顶替待删除节点的位置
   527  		successor := minimum(n.right)
   528  		successor.right = removeMin(n.right)
   529  		successor.left = n.left
   530  		successor.size = n.size - 1
   531  		successor.depth = n.depth
   532  		n.left = nil
   533  		n.right = nil
   534  		return successor
   535  	}
   536  }
   537  
   538  func (t *BST) String() string {
   539  	var sb strings.Builder
   540  	//generateBSTString(t.root, 0, &sb)
   541  	generateBSTLevelString(t.root, &sb)
   542  	return sb.String()
   543  }
   544  
   545  func generateBSTLevelString(n *node, sb *strings.Builder) {
   546  	l := list.New()
   547  	l.PushBack(n)
   548  	//curDepth := 0
   549  
   550  	curNodeCnt := 1
   551  	nextNodeCnt := 0
   552  	for l.Len() != 0 {
   553  		n, _ := l.Remove(l.Front()).(*node)
   554  		//if n.depth > curDepth {
   555  		//	curDepth = n.depth
   556  		//	sb.WriteRune('\n')
   557  		//}
   558  
   559  		sb.WriteString(fmt.Sprintf("%v ", n.val))
   560  		curNodeCnt--
   561  		if n.left != nil {
   562  			l.PushBack(n.left)
   563  			nextNodeCnt++
   564  		}
   565  		if n.right != nil {
   566  			l.PushBack(n.right)
   567  			nextNodeCnt++
   568  		}
   569  		if curNodeCnt == 0 {
   570  			sb.WriteRune('\n')
   571  			curNodeCnt = nextNodeCnt
   572  			nextNodeCnt = 0
   573  		}
   574  	}
   575  }
   576  
   577  func generateBSTString(n *node, depth int, sb *strings.Builder) {
   578  	if n == nil {
   579  		//generateDepthString(depth, sb)
   580  		//sb.WriteString("\n")
   581  		return
   582  	}
   583  	generateDepthString(depth, sb)
   584  	sb.WriteString(fmt.Sprintf("val:%v,child:%d,dh:%d\n", n.val, n.size-1, n.depth))
   585  	generateBSTString(n.left, depth+1, sb)
   586  	generateBSTString(n.right, depth+1, sb)
   587  }
   588  
   589  func generateDepthString(depth int, sb *strings.Builder) {
   590  	for i := 0; i < depth; i++ {
   591  		sb.WriteString("--")
   592  	}
   593  }