Features of the Binary Search Tree:
(1) All nodes on the left must be smaller than the value of the root node.
(2) All nodes on the right must be smaller than the value of the root node.
(3) the Subtrees of the original tree comply with the (1) (2) conditions.
The binary search tree is also known as the binary sorting tree, because you only need to traverse it in the middle order to get the sorting tree. The operations on the binary sorting tree are mainly as follows:
(1) Insert: Initialize the tree through insert. This article uses a chain instead of an array.
(2) traversal: There are three methods: first, middle, and last.
(3) Search: There are three types of searches: Find the maximum value, minimum value, and a node with a specific value.
(4) Delete: There are three types of Delete nodes: nodes with no left or right children, nodes with one child and nodes with two children.
A tree consists of edges between nodes. Therefore, you must first declare a Node class Node. A Node has two children and Node values.
public class Node{ public int value; public Node leftChild; public Node rightChild; public Node(int value) { leftChild = null; rightChild = null; this.value = value; }}
After the node class declaration is complete, you also need a tree class that contains tree initialization and some operations on the tree, A default constructor is used to initialize the value of an empty tree and an output point.
class BinarySearchTree{ public Node root; public BinarySearchTree() { root = null; } public void Dispaly(Node node) { Console.Write(node.value + " "); }}
To form a tree, you have to insert a value. According to the nature of the binary sorting tree, the left-side children's values are all smaller than the root node's values. Therefore, when inserting a value
(1) first, judge whether it is an empty tree, that is, whether the root node is empty. If it is empty, the inserted value is placed into the root node.
(2) determine the size of the value and the value of the root node (the root of the tree, or its Child number) to determine whether the child is left or right.
public void Insert(int v){ Node newNode = new Node(v); Node parent; Node current; if (root == null) root = newNode; else { current=root; while (true) { parent=current; if (v < current.value) { current = current.leftChild; if (current == null) { parent.leftChild = newNode; break; } } else { current = current.rightChild; if (current == null) { parent.rightChild = newNode; break; } } } }}
After the insertion is complete, a tree is formed. Now let's traverse the three types of traversal and implement them recursively to make the logic clearer.
public void InOrder(Node root){ Node node = root; if (node != null) { InOrder(node.leftChild); this.Dispaly(node); InOrder(node.rightChild); }}public void PreOrder(Node root){ Node node = root; if (node != null) { this.Dispaly(node); PreOrder(node.leftChild); PreOrder(node.rightChild); }}public void PostOrder(Node root){ Node node = root; if (node != null) { PostOrder(node.leftChild); PostOrder(node.rightChild); this.Dispaly(node); }}
The three traversal types have different order of the root node. The next step is to find the maximum, minimum, and specific values in the tree.
(1) maximum value: the child on the rightmost side of the tree
(2) Minimum value: child on the far left of the tree
(3) specific value: Use a loop to determine the size of the root value.
public Node FindMax(){ Node current=root; while (current.rightChild != null) current = current.rightChild; return current;}public Node FindMin(){ Node current = root; while (current.leftChild != null) current = current.leftChild; return current;}public Node Find(int v){ Node current = root; while (true) { if (v < current.value) current = current.leftChild; else if (v > current.value) current = current.rightChild; else return current; if (current == null) return null; }}
The last step is to delete the node. Because the number is composed of links, the method for deleting a node in the tree is similar to that for deleting a node in the linked list, but the changed "Pointer" is a little more, because the node of the tree is one-to-many. Use the if-else statement to differentiate the three types of deleted nodes.
Public bool Delete (int v) {Node current = root; Node parent = current; // locate the Node to be deleted while (current. value! = V) {parent = current; if (v <current. value) {current = current. leftChild;} else {current = current. rightChild;} if (current = null) return false;} // if there is no child node if (current. leftChild = null & current. rightChild = null) {if (current = root) root = null; if (current = parent. leftChild) parent. leftChild = null; if (current = parent. rightChild) parent. rightChild = null;} // if it is a node with the right child els E if (current. rightChild! = Null) {if (current = root) root = current. leftChild; if (current = parent. leftChild) parent. leftChild = current. rightChild; if (current = parent. rightChild) parent. rightChild = current. rightChild;} // if it is a node with a left child, else if (current. leftChild! = Null) {if (current = root) root = current. rightChild; if (current = parent. leftChild) parent. leftChild = current. leftChild; if (current = parent. rightChild) parent. rightChild = current. leftChild;} // Node with two children else {Node newNode = GetSuccessor (current); newNode. rightChild = current. rightChild; newNode. leftChild = current. leftChild; if (current = parent. leftChild) parent. leftChild = newNode; if (current = parent. rightChild) parent. rightChild = newNode;} return true ;}
The method for finding a successor node is as follows:
/// <Summary> /// When deleting a node with two children, delNode // successor of the right adjacent node (the deleted node is the root node of the subtree, the leftmost // node to replace the deleted node, because the successor value is greater than the smallest of the delNode values /// </summary> /// <param name = "delNode"> </param> /// <returns> </returns> private Node GetSuccessor (Node delNode) {Node current = delNode; while (current. leftChild! = Null) current = current. leftChild; return current ;}
The test is as follows:
Static void Main (string [] args) {BinarySearchTree bs = new BinarySearchTree (); bs. insert (2); bs. insert (5); bs. insert (6); bs. insert (10); bs. insert (12); bs. insert (15); bs. insert (18); bs. inOrder (bs. root); Console. writeLine ("maximum number: {0}", bs. findMax (). value); Console. writeLine ("minimum number: {0}", bs. findMin (). value); Console. writeLine ("found node value: {0}", bs. find (6 ). value); bs. delete (5); bs. inOrder (bs. root); Console. readKey ();}
Output:
Summary:
(1) to understand the basic principle of the binary sorting tree, we need to apply it.
(2) There should be a sequential storage method. This article uses a chain.
(3) from simplicity to simplicity.
(4) if there is an error or suggestion please explain in the reply or send zabery@126.com