Write a Binary Search Tree from Scratch | A Helpful Line-by-Line Code Tutorial | Part 1

class Node{
	
	int data;
	Node right;
	Node left;
	static int noOfNodes = 0;
	
	Node(int data){
		
		this.data = data;
		noOfNodes++;
		
	}
	
}

class BinaryTree {

	Node root;
	Node current;

	int noOfLeafNodes;
	int noOfOneChildNodes;
	int noOfTwoChildNodes;

	BinaryTree() {

		noOfLeafNodes = 0;
		noOfOneChildNodes = 0;
		noOfTwoChildNodes = 0;

	}

	public int noOfLeafNodes(Node temp) {

		if (temp != null) {

			if (temp.right == null && temp.left == null) {

				noOfLeafNodes++;

			}

			noOfLeafNodes(temp.right);
			noOfLeafNodes(temp.left);

			return noOfLeafNodes;

		}

		return 0;

	}

	public int noOfOneChildNodes(Node temp) {

		if (temp != null) {

			if (temp.right != null && temp.left == null) {

				noOfOneChildNodes++;

			}
			
			if (temp.right == null && temp.left != null) {

				noOfOneChildNodes++;

			}

			noOfOneChildNodes(temp.right);
			noOfOneChildNodes(temp.left);

			return noOfOneChildNodes;

		}

		return 0;

	}
	
	public int noOfTwoChildNodes(Node temp) {

		if (temp != null) {

			if (temp.right != null && temp.left != null) {

				noOfTwoChildNodes++;

			}

			noOfTwoChildNodes(temp.right);
			noOfTwoChildNodes(temp.left);

			return noOfTwoChildNodes;

		}

		return 0;

	}

	public void addNode(int data) {

		Node node = new Node(data);

		if (root == null) {

			root = node;
			root.right = null;
			root.left = null;

		} else {

			current = root;

			while (true) {

				if (data < current.data) {

					if (current.left == null) {

						current.left = node;
						current.left.right = null;
						current.left.left = null;

						break;

					} else {

						current = current.left;

					}

				} else {

					if (current.right == null) {

						current.right = node;
						current.right.right = null;
						current.right.left = null;

						break;

					} else {

						current = current.right;

					}

				}

			}

		}

	}

	public void delete(int data) {

		while (true) {

			if (data < current.data) {

				current = current.left;

			} else if (data > current.data) {

				current = current.right;

			} else if (data == current.data) {

				System.out.println("Well, the node to be deleted is "
						+ current.data);
				deleteNode(current);
				break;

			}

		}

	}

	public void deleteNode(Node deleteNode) {

		if (deleteNode.right == null && deleteNode.left == null) {

			System.out.println("Deleting Node...");

			current = root;

			while (true) {

				if (current.right.data == deleteNode.data) {

					current.right = null;
					break;

				} else if (current.left.data == deleteNode.data) {

					current.left = null;
					break;

				} else if (current.data < deleteNode.data) {

					current = current.right;

				} else if (current.data > deleteNode.data) {

					current = current.left;

				}

			}

		} else if (deleteNode.right != null && deleteNode.left == null) {

			int temp;

			temp = deleteNode.data;
			deleteNode.data = deleteNode.right.data;
			deleteNode.right.data = temp;

			deleteNode(deleteNode.right);

		} else if (deleteNode.right == null && deleteNode.left != null) {

			int temp;

			temp = deleteNode.data;
			deleteNode.data = deleteNode.left.data;
			deleteNode.left.data = temp;

			deleteNode(deleteNode.left);

		} else if (deleteNode.right != null && deleteNode.left != null) {

			int temp;

			temp = deleteNode.data;
			deleteNode.data = deleteNode.right.data;
			deleteNode.right.data = temp;

			deleteNode(deleteNode.right);

		}

	}

	public void print() {

		System.out.println("PreOrder");
		preOrder(root);
		System.out.println();
		System.out.println("InOrder");
		inOrder(root);
		System.out.println();
		System.out.println("PostOrder");
		postOrder(root);
		System.out.println();

	}

	private void postOrder(Node temp) {

		if (temp != null) {

			postOrder(temp.left);
			postOrder(temp.right);
			System.out.print(temp.data + " ");

		}

	}

	private void inOrder(Node temp) {

		if (temp != null) {

			inOrder(temp.left);
			System.out.print(temp.data + " ");
			inOrder(temp.right);

		}

	}

	private void preOrder(Node temp) {

		if (temp != null) {

			System.out.print(temp.data + " ");
			preOrder(temp.left);
			preOrder(temp.right);

		}

	}

}

class Main {

	public static void main(String[] args) {

		BinaryTree b = new BinaryTree();

		//for (int i = 0; i < 5; i++) {

			///int rand = (int) (Math.random() * 100);
			//b.addNode(rand);

		//}

		 b.addNode(5);
		 b.addNode(3);
		 b.addNode(4);
		 b.addNode(1);
		 b.addNode(9);

		 b.delete(9);
		
		System.out.println("The amount of leafNodes are "
				+ b.noOfLeafNodes(b.root));
		System.out.println("The amount of Nodes with 1 children are "
				+ b.noOfOneChildNodes(b.root));
		System.out.println("The amount of Nodes with 2 child are "
				+ b.noOfTwoChildNodes(b.root));

		b.print();

	}

}