github.com/searKing/golang/go@v1.2.117/container/trie_tree/ternary_search_tree/tst.go (about)

     1  // Copyright 2020 The searKing Author. All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  // https://en.wikipedia.org/wiki/Ternary_search_tree
     6  // In computer science, a ternary search tree is a type of trie (sometimes called a prefix tree)
     7  // where nodes are arranged in a manner similar to a binary search tree,
     8  // but with up to three children rather than the binary tree's limit of two.
     9  // Like other prefix trees, a ternary search tree can be used as an associative map structure
    10  // with the ability for incremental string search.
    11  // However, ternary search trees are more space efficient compared to standard prefix trees,
    12  // at the cost of speed. Common applications for ternary search trees include spell-checking and
    13  // auto-completion.
    14  package ternary_search_tree
    15  
    16  import (
    17  	"github.com/searKing/golang/go/container/traversal"
    18  )
    19  
    20  // TernarySearchTree represents a Ternary Search Tree.
    21  // The zero value for List is an empty list ready to use.
    22  type TernarySearchTree struct {
    23  	root node // sentinel list node, only &root, root.prev, and root.next are used
    24  }
    25  
    26  // Init initializes or clears tree l.
    27  func (l *TernarySearchTree) init() *TernarySearchTree {
    28  	l.root.left = &l.root
    29  	l.root.middle = &l.root
    30  	l.root.right = &l.root
    31  	l.root.tree = l
    32  	return l
    33  }
    34  
    35  // New creates a tenary search tree, which is a trie tree.
    36  func New(prefixes ...string) *TernarySearchTree {
    37  	tree := (&TernarySearchTree{}).init()
    38  	for _, prefix := range prefixes {
    39  		tree.Store(prefix, nil)
    40  	}
    41  	return tree
    42  }
    43  
    44  // NewWithBytes behaves like New, but receive ...[]byte
    45  func NewWithBytes(prefixes ...[]byte) *TernarySearchTree {
    46  	tree := (&TernarySearchTree{}).init()
    47  	for _, prefix := range prefixes {
    48  		tree.Store(string(prefix), nil)
    49  	}
    50  	return tree
    51  }
    52  
    53  // Depth return max len of all prefixs
    54  func (l *TernarySearchTree) Depth() int {
    55  	return l.root.Depth()
    56  }
    57  
    58  // Count returns the number of elements of list l, excluding (this) sentinel node.
    59  func (l *TernarySearchTree) Count() int {
    60  	var len int
    61  	l.Traversal(traversal.Preorder, HandlerFunc(func(prefix []byte, value any) (goon bool) {
    62  		len++
    63  		return true
    64  	}))
    65  	return len
    66  }
    67  
    68  // Front returns the first node of list l or nil if the list is empty.
    69  func (l *TernarySearchTree) Left() *node {
    70  	return l.root.left
    71  }
    72  
    73  // Middle returns the first node of list l or nil if the list is empty.
    74  func (l *TernarySearchTree) Middle() *node {
    75  	return l.root.middle
    76  }
    77  
    78  // Right returns the first node of list l or nil if the list is empty.
    79  func (l *TernarySearchTree) Right() *node {
    80  	return l.root.right
    81  }
    82  
    83  // lazyInit lazily initializes a zero List value.
    84  func (l *TernarySearchTree) lazyInit() {
    85  	if l.root.right == nil {
    86  		l.init()
    87  	}
    88  }
    89  
    90  func (l *TernarySearchTree) Traversal(order traversal.Order, handler Handler) {
    91  	l.root.Traversal(order, handler)
    92  }
    93  
    94  // Follow returns node info of longest subPrefix of prefix
    95  func (l *TernarySearchTree) Follow(prefix string) (key string, value any, ok bool) {
    96  	pre, val, ok := l.root.Follow([]byte(prefix))
    97  	return string(pre), val, ok
    98  }
    99  
   100  // Load loads value by key
   101  func (l *TernarySearchTree) Load(key string) (value any, ok bool) {
   102  	return l.root.Load([]byte(key))
   103  }
   104  
   105  // Store stores value by key
   106  func (l *TernarySearchTree) Store(key string, value any) {
   107  	l.root.Store([]byte(key), value)
   108  }
   109  
   110  // return true if the node matched with key, with value nonempty
   111  func (l *TernarySearchTree) Contains(key string) bool {
   112  	return l.root.Contains([]byte(key))
   113  }
   114  
   115  // return true if any node exists with key prefix, no matter value is empty or not
   116  func (l *TernarySearchTree) ContainsPrefix(prefix string) bool {
   117  	return l.root.ContainsPrefix([]byte(prefix))
   118  }
   119  
   120  // remove the node matched with key
   121  func (l *TernarySearchTree) Remove(key string, shrinkToFit bool) (old any, ok bool) {
   122  	return l.root.Remove([]byte(key), shrinkToFit)
   123  }
   124  
   125  // remove all nodes started with key prefix
   126  func (l *TernarySearchTree) RemoveAll(prefix string) (old any, ok bool) {
   127  	return l.root.RemoveAll([]byte(prefix))
   128  }
   129  
   130  func (l *TernarySearchTree) String() string {
   131  	return l.root.String()
   132  }