Symbol table (3)--Two fork find tree
This series of articles mainly introduces the knowledge of commonly used algorithms and data structures, records the contents of "Algorithms i/ii" course, adopts "algorithm (4th edition)" This Red Cookbook as a learning material, language is java. I don't have to say much about the fame of this book. Watercress Rating 9.4, I myself also think is an excellent learning algorithm books.
With this series of articles, you can deepen your understanding of data structures and basic algorithms (individuals think more clearly than schools) and deepen their understanding of Java.
-
- Symbol Table 32 Fork Find tree
- Binary search Tree
- 1 Code Framework
- 2 node representation
- 3 Getting the operation
- 4 Insert Operation
- 5 Animated Demos
- 62 The shape of a fork tree
- Orderly operation
- 1 Maximum Minimum
- 2 Floor and ceiling
- Floor Operation Recursive operation
- Ceiling Operation Recursive operation
- 3 Sub-tree statistics
- 4 Rank
- 5 Sequential traversal
- Summarize
12 fork Find Tree
Binary search tree is a symmetrical and ordered two-fork tree
That
Each node has a key, there are 2 children, the left child's key is smaller than its own key, the right child's key is greater than its own key. (Not the same as the heap)
1.1 Code Framework
We can design a basic framework of the two-fork search tree according to the definition and then refine it
Public class BST<key extends comparable<key; Value>{ PrivateNode Root;Private class Node{} Public void put(Key key, Value Val) {} PublicValueGet(Key key) {} Public void Delete(Key key) {} PublicIterable<key>iterator(){}}
1.2 Node Representation
As a binary lookup tree node, it should contain key-value, and left and right children
privateclass Node { private Key key; private Value val; private Node left, right; publicNode(Key key, Value val) { this.key = key; this.val = val; } }
1.3 Getting the Operation
Depending on the nature of the binary tree, you can start by searching from root:
- If less than, left child
- If greater than, right child
- If found, returns
- If NULL, the failure is achieved
publicget(Key key) { Node x = root; whilenull) { int cmp = key.compareTo(x.key); if0) x = x.left; elseif0) x = x.right; elseif0) return x.val; } returnnull; }
1.4 Insert Operation
The insert operation can be done with a recursive return. (in any case involving the insertion of linked lists, you can consider recursion, with the non-recursive relative trouble points, because the insert operation is to insert a child on the Father node, if the root is empty also have to judge separately)
Continue to search around the child until a null node is found, put the new < key, value > Insert. If the key itself is in the tree, the value is updated.
Here the more ingenious is: root = put(root, key, val)
;
The root was also incorporated.
Public void put(Key key, Value Val) {root = put (root, Key, Val); }PrivateNodeput(Node x, key key, Value Val) {if(x = =NULL) {return NewNode (Key, Val); }intCMP = Key.compareto (X.key);if(CMP <0{X.left = put (X.left, Key, Val); }Else if(CMP >0{x.right = put (X.right, Key, Val); }Else if(CMP = =0) {x.val = val; }returnX }
You can also use non-recursive code:
Public void put(Key Key,value Val) {Node x = root;if(x = =NULL) x =NewNode (Key,val); while(true) {intCMP = Key.compareto (X.key);if(CMP <0) {if(X.left! =NULL) x = X.left; X.left =NewNode (Key,val);return; }if(CMP >0) {if(X.right! =NULL) x = X.right; X.right =NewNode (Key,val);return; }if(CMP = =0) {x.val = val;return; } } }
1.5 Animated demos
Animate demo Find and insert
1.6 Two The shape of a fork tree
Depending on the insertion order, the binary tree will show a different shape, the best state of course is the state of full balance, this time the search efficiency is the most efficient, the worst form is the sequence of inserting, this time the binary tree search efficiency is n.
Let's look at the effects of random insertions:
Studies have shown that the average depth of the binary tree is not deep, if the insertion is random. Therefore, the efficiency of the binary tree is still very high.
2. Orderly Operation
2.1 Maximum Minimum
This is very simple, the biggest words directly search the right child
The smallest of words, direct search to the left child
2.2 Floor and ceiling
floor
: Find the largest key smaller than key
ceiling
: Find the smallest key larger than key
2.2.1 Floor Operation: (Recursive operation)
Since floor operations are looking for the largest key that is smaller than key, this concept looks particularly round, so it has to be clear.
- Condition One: first, the precondition is more than the given key 小
- Condition Two: then 小
find one in these values 最大
.
Let's consider how to find the floor value of a node if given to you?? Obviously, it's 左子树
(condition 1) 最右节点
(condition 2), so the following train of thought is like this, first satisfies the condition 1, then satisfies the condition 2.
- if k = =
root.key
floor
=root.key
- If K <
root.key
左子树
continues to look up (miscellaneous no smaller than me)
- If k >
root.key
record root
(finally found a smaller than me, hurriedly write it down)
- If you
右边子树
encounter a 小于
K, go ahead (see if you have a larger 小
value)
- Otherwise,
root
it is (there seems to be no bigger than you)
PublicKey Floor(Key key) {Node x = floor (Root,key);if(x = =NULL)return NULL;returnX.key; }PrivateNode Floor(Node X,key Key) {if(x = =NULL)returnXintCMP = Key.compareto (X.key);if(CMP <0)returnFloor (x.left, key);if(CMP = =0)returnX Node f = Floor (x.right, key);if(f = =NULL)returnXElse returnF }
2.2.2 Ceiling operation: (Recursive operation)
As opposed to floor operation
- if k = =
root.key
floor
=root.key
- If k >
root.key
右子树
continues to look up (miscellaneous no bigger than me?)
- If k <
root.key
Records root
(finally found a bigger than me, hurriedly write down)
- If you
左边子树
encounter a 大于
K, go ahead (see if there is a smaller 大
value)
- Otherwise,
root
it is (there seems to be no smaller than you)
PublicKeyCeil(Key key) {Node x = ceil (root, key);if(x = =NULL) {return NULL; }returnX.key; }PrivateNodeCeil(Node x, key key) {if(x = =NULL) {returnX }intCMP = Key.compareto (X.key);if(CMP >0) {returnCeil (X.right, key); }if(CMP = =0) {returnX } Node F = ceil (X.left, key);if(f = =NULL) {returnX }Else{returnF } }
2.3 Sub-tree statistics
Subtree Statistics there are many applications, we often need to find a smaller than the number of keys, or find the first few elements, such as rank()
operation, select()
operation.
First, we need to add a variable count to the node class that counts. and modify the size () and put function so that when the tree is established, it makes count fill well.
privateclass Node{ private Key key; private Value val; private Node left; private Node right; privateint count; //加这里}
publicintsize() { return size(root); } privateintsize(Node x) { ifnullreturn0; return x.count; //加这里 }
PrivateNodeput(Node x, key key, Value Val) {if(x = =NULL)return NewNode (Key, Val,1);intCMP = Key.compareto (X.key);if(CMP <0) X.left = put (X.left, Key, Val);Else if(CMP >0) X.right = put (X.right, Key, Val);Else if(CMP = =0) X.val = Val; X.count =1+ Size (x.left) + size (x.right);//Add here returnX }
2.4 rank ()
Rank's function is to return the number of keys less than key. There are three types of cases:
- Root = = Key
Left child count
(because only the left child is smaller than it)
- Root < Key
Left child count
+1 (self) + right child continue to find
- Root > Key
The left child continues to look for (the given key has not found a smaller than its own)
For example, in this diagram:
Rank (S) = 6
Rank (A) = 0 (left child is null)
Rank (D) = 0+1+0+1 = 2 (1 is a and C themselves, 0 is a and C's left child)
Public int Rank(Key key) {returnRank (Root,key); }Private int Rank(Node X,key Key) {if(x = =NULL)return 0;intCMP = Key.compareto (X.key);if(CMP >0)return 1+ Size (x.left) + rank (x.right,key);Else if(CMP = =0)returnSize (x.right);returnRank (X.left,key); }
2.5 Sequential Traversal
According to the structure of the binary tree, it is very simple:
- Traverse left Child
- Insert your key into the queue
- Traverse Right Child
publickeys() { new Queue<Key>(); inorder(root, q); return q; } privatevoidinorder(Node x,Queue<Key> q) { ifnull) return ; inorder(x.left, q); q.enqueue(x.key); inorder(x.right,q); }
3 Summary
Using binary sorting tree to implement the symbol table operation, its time complexity is larger than the other way.
The attentive little partner may have found out that we did not speak the delete operation, because the delete operation involves more things, we speak it separately in the back.
Common algorithms and data structures symbol table ST (3)--Two fork Find tree (animation)