BST is mainly used to realize the function of lookup tables, through Key to find the corresponding Value, similar to the daily dictionary. Not only can CRUD be efficient, data maintenance, but also can be used to find min, max, floor, ceil, rank, select and so on.
^ v ^ Author will not do Key-Value demonstration here, just replace it with Value...
First, you need to define a class as an entity
public class BSTNode {
private int num;//data
BSTNode leftNode;//Left tree
BSTNode rightNode;//Right subtree
BSTNode parent;/*Represents the parent node, and the root node is null.
The main purpose is to delete nodes smoothly.*/
public BSTNode() {
super();
}
public BSTNode(int num) {
super();
this.num = num;
this.leftNode = null;
this.rightNode = null;
this.parent = null;
}
getandset
@Override
public String toString() {
. . . /*Be careful to remove the field of the print parent, or you'll fall into circular mode.
From father to son, then from son to father, this infinite reading mode*/
}
}
Next is the key point, CRUD (although the author has not changed here, but the reader can achieve their own, in fact, is the coverage operation, also can not see what effect)
This defines some global variables:
public static BSTNode result;
// When a value cannot be found, it is used to store the last node for easy insertion.
static Queue<BSTNode> queue = new LinkedList<BSTNode>();
ergodic
Depth priority is as follows:
/**
* Traveling through the whole tree in a neutral order, recursively noticing the conditions for the end
* @param root Root node of binary tree to be traversed
*/
public static void Traverse(BSTNode root) {
if (root == null) {
return;
}
Traverse(root.getLeftNode());
System.out.print(root.getNum() + " ");
Traverse(root.getRightNode());
}
The breadth priority is as follows:
/**
* Traversing the whole tree in a breadth-first way
* @param root Trees to traverse
*/
public static void TraverseSpan(BSTNode root) {
if (root == null) {
return;
}
queue.offer(root);
//Because add() and remove() methods throw exceptions when they fail (not recommended)
while (!queue.isEmpty()) {
BSTNode poll = queue.poll();
//Returns the first element and deletes it from the queue
if (poll.getLeftNode() != null) {//The left node joining the node
queue.offer(poll.getLeftNode());
}
if (poll.getRightNode() != null) {//The right node joining the node
queue.offer(poll.getRightNode());
}
System.out.print(poll.getNum() + " ");
}
}
lookup
Find max
/**
* Get the maximum node of the incoming BST
*
* @param root
* @return
*/
public static BSTNode GetMax(BSTNode root) {
if (root == null)
return null;
while (root.getRightNode() != null) {
root = root.getRightNode();
}
return root;
}
Find min
/**
* Get the minimum value node of the incoming BST
*
* @param root
* @return
*/
public static BSTNode GetMin(BSTNode root) {
if (root == null)
return null;
while (root.getLeftNode() != null) {
root = root.getLeftNode();
}
return root;
}
Find any number
/**
* Check to see if there is a target value to look for in the balanced binary tree
*
* @param root Root node of balanced binary tree to be found
* @param target Target value to look for
* @param parent The parent node of the root node of the balanced binary tree currently passed into the Find function,
* Not at first, null is introduced, which paves the way for other operations of balancing binary trees.
* @return Find or not
*/
public static boolean Find(BSTNode root, int target, BSTNode parent) {
if (root == null) {
// Traverse to the leaf node, can not find, return false, and as the end condition of recursion
result = parent;
return false;
}
if (root.getNum() == target) { // Find your target
result = root;
return true;
} else if (root.getNum() > target) {
// your target is too small
return Find(root.getLeftNode(), target, root);
} else { // your target is too big
return Find(root.getRightNode(), target, root);
}
}
insert
/**
* Insert a node into BST
*
* @param root Root node of BST to insert node
* @param value Values to be inserted
* @returnIf the insertion succeeds, the insertion fails if the number already exists.
*/
public static boolean Insert(BSTNode root, int value) {
if (Find(root, value, null)) {
// Find the value to insert, no duplicate values can appear, so return false
return false;
}
// If it cannot be found, then the parent node of the point to be inserted is known by the result obtained when it cannot be found above.
BSTNode nodeTemp = new BSTNode();
nodeTemp.setNum(value);
nodeTemp.setParent(result);
if (result.getNum() > value) {
// Value is smaller than the value of node and is placed in the left subtree of node
result.setLeftNode(nodeTemp);
} else {
result.setRightNode(nodeTemp);
}
return true;
}
delete
/**
* Delete any node
*
* @param root BST to be operated
* @param value Number to be deleted
* @returnDelete successfully returns true, otherwise return false
*/
public static boolean Delete(BSTNode root, int value) {
if (root == null) {// Determine whether the incoming tree is empty
return false;
}
if (root.getNum() == value) {
// If the target value is the root node, enter the deleted subfunction
return DeleteNode(root);
} else if (root.getNum() > value) {
// When the target value is small, it enters the left subtree for further judgment.
return Delete(root.getLeftNode(), value);
} else {// If the target value is large, it will enter the right subtree for further judgment.
return Delete(root.getRightNode(), value);
}
}
/**
* To delete nodes, do specific operations
*
* @param root BST to be operated
* @returnDelete successfully returns true, otherwise return false
*/
public static boolean DeleteNode(BSTNode root) {
BSTNode parent = root.getParent();
// Simplify operations by adding an attribute to an entity object
if (root.getLeftNode() == null) {// No left subtree
if (parent.getLeftNode() == root) {
parent.setLeftNode(root.getRightNode());
} else {
parent.setRightNode(root.getRightNode());
}
return true;
}
if (root.getRightNode() == null) {// The absence of right subtrees
if (parent.getLeftNode() == root) {
parent.setLeftNode(root.getLeftNode());
} else {
parent.setRightNode(root.getLeftNode());
}
return true;
}
BSTNode getMax = GetMax(root.getRightNode());
// The situation of both left and right subtrees
if (parent.getLeftNode() == root) {
parent.setLeftNode(getMax);
} else {
parent.setRightNode(getMax);
}
getMax.setLeftNode(root.getLeftNode());
// Don't miss the left subtree of root and connect it again
DeleteNode(getMax);
return true;
}
The tests are as follows:
Since insert hasn't been written at first, you have to configure your own new objects and then configure their relationships.
public static void main(String[] args) {
//Some new objects come out
BSTNode n1 = new BSTNode(59);
BSTNode n2 = new BSTNode(40);
BSTNode n3 = new BSTNode(69);
BSTNode n4 = new BSTNode(20);
BSTNode n5 = new BSTNode(49);
BSTNode n6 = new BSTNode(66);
BSTNode n7 = new BSTNode(45);
BSTNode n8 = new BSTNode(52);
BSTNode n9 = new BSTNode(41);
//Manual configuration of relationships between objects
n9.setParent(n7);
n8.setParent(n5);
n7.setParent(n5);
n7.setLeftNode(n9);
n6.setParent(n3);
n5.setParent(n2);
n5.setLeftNode(n7);
n5.setRightNode(n8);
n4.setParent(n2);
n3.setParent(n1);
n3.setLeftNode(n6);
n2.setParent(n1);
n2.setLeftNode(n4);
n2.setRightNode(n5);
n1.setLeftNode(n2);
n1.setRightNode(n3);
/*It can also be injected automatically.
* BSTNode n1 = new BSTNode(40);
*
* int[] temp = new int[]{59,69,66,49,20,45,41,52}; for(int i : temp){
* Insert(n1, i); }
*/
Traverse(n1);//Depth first
System.out.println();
System.out.println("*******Breadth first can also:********");
TraverseSpan(n1);
/*
* System.out.println();
*
* int getMax = GetMax(n1).getNum(); System.out.println("max="+getMax);
*
* int getMin = GetMin(n1).getNum(); System.out.println("min="+getMin);
*
* boolean Find = Find(n1, 59, null); System.out.println(Find);
* System.out.println(result);
*
*
* boolean insert = Insert(n1, 65); if(insert){
* System.out.println("****Insert the following ***********“); Traverse(n1); }
*
* System.out.println();
*
* boolean delete = Delete(n1, 49); if(delete){
* System.out.println("*****Deleted as follows: ******************“); Traverse(n1); }
*/
}
Conclusion:
1. In the process of BST writing, the author did not use the attribute of a parent at the beginning, so he stuck in the place of deleting a node. It was the parent that joined the parent that had no effect on the code that had been written before. However, the problem of deleting a node was solved at once. So, if there are any problems in the future, we can try to add a subordinate with the help of this idea. Sex, or when a function is called, adding one more variable may make it easy to solve the problem.
2. Recursive solution ideas, when to take what steps, what scope, try to experience.