* What is a two-fork search tree? The form is a binary tree, for each node x, the value of its left subtree <=x.value, the value of the right subtree >=x.value.
* For binary search trees, we can use the middle order traversal to get all the elements from small to large on the tree. The average time complexity is O (n).
function Inordertreewalk (x) { ifnull) { inordertreewalk (x.left); Print (X.key); Inordertreewalk (x.right); } }
* What do we do when we want to query a keyword in a binary search tree? Since the binary search tree Saozi the right subtree, it is easy to write:
function Treesearch (x,k) { // start x represents the root node ifnull | | x.key = = = k) { return x; } if (K < x.key) { return treesearch (X.left, k); Else { return treesearch (X.right, k); }}
We can also write loop versions (generally more efficient than recursion):
function Treesearch (x, k) { whilenull | | k!== x.key) { if(K < X.key ) { = x.left; Else { = x.right; } } return x;}
* It's easy to find the smallest and largest elements in a two-fork search tree, with a lookup time complexity of O (LGN):
function treeminimum (x) { whilenull) { = x.left; } return x;} function treemaximum (x) { whilenull) { = x.right; } return x;}
* Sometimes we need to traverse the middle order to find the successor and precursor of a node in the binary search tree. The analysis of binary search tree properties shows that if the right subtree of the node is not empty, its successor should be the smallest element in the right subtree, and if the right subtree is empty, then the successor of the node should be the parent node whose parents have Zuozi. The precursor is symmetrical. Time complexity O (LGN):
functionTreesuccessor (x) {//Successor Search if(X.right!==NULL) { returnTreeminimum (x.right); } Else{let y=x.parent; while(Y!==NULL&& x = = =y.right) {x=y; Y=y.parent; } returny; }}functionTreesuccessor (x) {//Precursor finder if(X.left!==NULL) { returnTreemaximum (X.left); } Else{let y=x.parent; while(Y!==NULL&& x = = =y.left) {x=y; Y=y.parent; } returny; }}
* Next we also want to implement insert and delete operations on the two-fork search tree.
1, the insertion is relatively simple, we simply traverse the binary tree to insert the value into the appropriate position on the line.
functionTreeinsert (tree, NewNode) {Let y=NULL; while(Tree!==NULL) {y=Tree; if(Newnode.key <tree.key) {tree=Tree.left; } Else{Tree=Tree.right; }} newnode.parent=y; if(y = = =NULL) {//The tree is emptyTree.root =NewNode; } Else { if(Newnode.key <y.key) {y.left=NewNode; } Else{y.right=NewNode; } }}
2, the deletion operation is relatively complex. If we delete the Z-node, we consider three cases: Z has no child nodes, Z has a child node, Z has two child nodes.
In the first case: Z has no child nodes, the z is deleted directly, the parent node property is modified, and null is substituted for Z.
Second case: Z has only one child node, then the child node is substituted for Z.
In the third case: Z has two sub-nodes, we need to find the successor of Z Y,y is definitely in the right subtree of z and there is no left child, when y happens to be the right child node of z, then use y instead of z and leave Y's right child; otherwise, use Y's right child node instead of Y and y instead of Z.
functionTransplant (tree, u, v) {//Subtree Substitution parent node method if(U.P = = =NULL) {Tree.root=v; } Else if(U = = =u.parent.left) {u.parent.left=v; } Else{u.parent.right=v; } if(v!==NULL) {v.parent=u.parent; }}functiontreedelete (tree, z) {if(Z.left = = =NULL) {transplant (tree, z, z.right); } Else if(Z.right = = =NULL) {transplant (tree, z, z.left); } Else{let y=Treeminimum (z.right); if(Y.parent!==z) {transplant (tree, y, y.right); Y.right=Z.right; Y.right.parent=y; } transplant (tree, z, y); Y.left=Z.left; Y.left.parent=y; }}
Binary search Tree JavaScript implementation