In: Computer Science
A binary search tree can be built with a traditional insertion
method given a list of integers. Binary search trees (BSTs) are
binary trees where the data is ordered such that nodes in the
subtree to the left of a given node are smaller than or equal to
the node, and the right subtree will contain nodes with values
greater than the given node. With a built binary search tree, one
can traverse the tree to print each node’s data in each order of
traversal or perform some other operations. Further, one can tell
by comparing nodes between two given trees whether they relate to
each other, by having a reflected symmetric structure (i.e. being
mirror images of each other), having identical structure, or not
being related at all. In this assignment, you are asked to
implement the following features.
Hard-code some paired lists of integers.
Build binary search trees from each list
Print the binary search trees in the three orders discussed in
class.
Determine if the two binary search trees are identical, mirrors of
each other, or neither
Remove a number in each tree at random and compare the tree pair
again
Further, since the methods of the binary search tree class have
been presented with recursive function calls, it is now up to you
to implement these recursive functions with iterative loops.
NO recursion with the methods. It needs to be done iteratively.
Class BinarySearchTree:
__root = None
Def __init__(self):
Self.__root = None
Def preorder(self, root):
# add code here to visit tree in
preorder traversal
Def inorder(self, root):
# add code here to visit tree in
inorder traversal
Def postorder(self, root):
# add code here to visit tree in
postorder traversal
Def insert(self, root, data):
# add code here to insert a
node
Def remove(self, root, data):
# add code here to remove a
node
Def search(self, root, data):
# add code here to search for a
datum in the tree
Def get_max(self, root)
# add code here to find max node of
this subtree
Def get_min(self, root):
# add code here to find min node of
this subtree
Class Node:
__data = None
__leftchild = None
__rightchild = None
Def __init__(self):
Self.__data = None
Self.__leftchild = None
Self.__rightchild = None
Class TreeChecker:
Def is_mirror(self, t1, t2):
# add code here to check if the
input tree pair are mirrors of each other.
# Return if true or false
Def is_same(self, t1, t2):
# add code here to check if the two
trees are identical. Return if true or false
Answer :
P.S : No doubt its a huge code please check it attentively before dislike it. I don't need a thumbsup but I just want you to check it minutely.
I have provided the class as asked in the question with the implementation of the interfaces.
**I have considered the data as Integer for the sack of simplicity you may edit it as per requirement**
class Node implements INode
{
int data;
Node left, right;
public Node(int item)
{
data = item;
left = right = null;
}
public setData(int data)
{
this.data = data;
}
public int getData()
{
return data;
}
public setLeftChild(Node left)
{
this.left = left;
}
public setRightChild(Node Right)
{
this.right = right;
}
public getLeftChild()
{
return left;
}
public getRightChild()
{
return right;
}
}
class BinarySearchTree implements ITree
{
Node root;
void setRoot(Node node)
{
Node(node);
}
Node getRoot()
{
return root;
}
public void preorder()
{
iterativePreorder(root);
}
// An iterative process to print preorder traversal of Binary
tree
void iterativePreorder(Node node)
{
// Base Case
if (node == null) {
return;
}
// Create an empty stack and push root to it
Stack<Node> ns = new Stack<Node>();
ns.push(root);
/* Pop all items one by one. Do following for every popped
item
a) print it
b) push its right child
c) push its left child
Note that right child is pushed first so that left is processed
first */
while (ns.empty() == false) {
// Pop the top item from stack and print it
Node n = ns.peek();
System.out.print(n.data + " ");
ns.pop();
// Push right and left children of the popped node to stack
if (n.right != null) {
ns.push(n.right);
}
if (n.left != null) {
ns.push(n.left);
}
}
}
void inorder()
{
if (root == null)
return;
Stack<Node> ns = new Stack<Node>();
Node curr = root;
// traverse the tree
while (curr != null || ns.size() > 0)
{
/* Reach the left most Node of the
curr Node */
while (curr != null)
{
/* place pointer to a tree node on
the stack before traversing
the node's left subtree */
ns.push(curr);
curr = curr.left;
}
/* Current must be NULL at this point */
curr = ns.pop();
System.out.print(curr.data + " ");
/* we have visited the node and its
left subtree. Now, it's right
subtree's turn */
curr = curr.right;
}
}
ArrayList<Integer> res = new
ArrayList<Integer>();
public void postorder()
{
res=postOrderIterative(root);
for (int i = 0; i < res.size(); i++)
System.out.print(res.get(i) + " ");
}
ArrayList<Integer> list = new ArrayList<Integer>();
// An iterative function to do postorder traversal
// of a given binary tree
ArrayList<Integer> postOrderIterative(Node node)
{
Stack<Node> S = new Stack<Node>();
// Check for empty tree
if (node == null)
return list;
S.push(node);
Node prev = null;
while (!S.isEmpty())
{
Node current = S.peek();
/* go down the tree in search of a leaf an if so process
it
and pop stack otherwise move down */
if (prev == null || prev.left == current ||
prev.right == current)
{
if (current.left != null)
S.push(current.left);
else if (current.right != null)
S.push(current.right);
else
{
S.pop();
list.add(current.data);
}
/* go up the tree from left node, if the child is right
push it onto stack otherwise process parent and pop
stack */
}
else if (current.left == prev)
{
if (current.right != null)
S.push(current.right);
else
{
S.pop();
list.add(current.data);
}
/* go up the tree from right node and after coming back
from right node process parent and pop stack */
}
else if (current.right == prev)
{
S.pop();
list.add(current.data);
}
prev = current;
}
return list;
}
static Node newNode(int data)
{
Node temp = new Node();
temp.key = data;
temp.left = null;
temp.right = null;
return temp;
}
public Node insert(Node root, int key)
{
// Create a new Node containing
// the new element
Node newnode = newNode(key);
// Pointer to start traversing from root and
// traverses downward path to search
// where the new node to be inserted
Node x = root;
// Pointer y maintains the trailing
// pointer of x
Node y = null;
while (x != null) {
y = x;
if (key < x.key)
x = x.left;
else
x = x.right;
}
// If the root is null i.e the tree is empty
// The new node is the root node
if (y == null)
y = newnode;
// If the new key is less then the leaf node key
// Assign the new node to be its left child
else if (key < y.key)
y.left = newnode;
// else assign the new node its right child
else
y.right = newnode;
// Returns the pointer where the
// new node is inserted
return y;
}
public void remove(Node root,int value) {
if (root == null) {
System.out.println("There are no nodes in this Binary Search
Tree");
}
else
{
Node currentNode = root;
Node parentNode = null;
while (true) {
if (value > currentNode.getData()) {
if (currentNode.getRightChild() != null) {
parentNode = currentNode;
currentNode = currentNode.getRightChild();
} else {
System.out.println("No Node is present with this value");
break;
}
} else if (value < currentNode.getData()) {
if (currentNode.getLeftChild() != null) {
parentNode = currentNode;
currentNode = currentNode.getLeftChild();
} else {
System.out.println("No Node is present with this value");
break;
}
} else {
if (currentNode.getLeftChild() == null
&& currentNode.getRightChild() == null) {
if (parentNode == null) {
rootNode = null;
} else if (parentNode.getLeftChild().getData() ==
currentNode.getData()) {
parentNode.setLeftChild(null);
} else {
parentNode.setRightChild(null);
}
} else if (currentNode.getLeftChild() == null) {
if (parentNode == null) {
root = currentNode.getRightChild();
} else if (parentNode.getLeftChild().getData() ==
currentNode.getData()) {
parentNode.setLeftChild(currentNode.getRightChild());
} else {
parentNode.setRightChild(currentNode.getRightChild());
}
} else if (currentNode.getRightChild() == null) {
if (parentNode == null) {
root = currentNode.getLeftChild();
} else if (parentNode.getLeftChild().getData() ==
currentNode.getData()) {
parentNode.setLeftChild(currentNode.getLeftChild());
} else {
parentNode.setRightChild(currentNode.getLeftChild());
}
} else {
int successorNodeValue =
getSuccessorNodeValue(currentNode.getRightChild());
delete(successorNodeValue);
currentNode.setData(successorNodeValue);
}
}
}
}
}
private int getSuccessorNodeValue(Node currentNode) {
while (true) {
if (currentNode.getLeftChild() != null) {
currentNode = currentNode.getLeftChild();
} else {
break;
}
}
return currentNode.getData();
}
public int search(Node root, int key)
{
// Traverse untill root reaches to dead end
while (root != null) {
// pass right subtree as new tree
if (key > root.data)
root = root.right;
// pass left subtree as new tree
else if (key < root.data)
root = root.left;
else
return key; // if the key is found return it otherwise return
-1
}
return -1;
}
public Node getMax(Node root)
{
Node current = root;
/* loop down to find the rightmost leaf */
while (current.right != null) {
current = current.right;
}
return (current);
}
public Node getMin(Node root) {
Node current = root;
/* loop down to find the leftmost leaf */
while (current.left != null) {
current = current.left;
}
return (current);
}
}
class TreeChecker implements ITreeChecker
{
public boolean isMirror(Node root1, Node root2) {
Stack<Node> st1 = new Stack<Node> ();
Stack<Node> st2 = new Stack<Node> ();
while (true)
{
// iterative inorder traversal of 1st tree and
// reverse inoder traversal of 2nd tree
while (root1 != null && root2 != null)
{
// if the corresponding nodes in the two traversal
// have different data values, then they are not
// mirrors of each other.
if (root1.data != root2.data)
return false;
st1.push(root1);
st2.push(root2);
root1 = root1.left;
root2 = root2.right;
}
// if at any point one root becomes null and
// the other root is not null, then they are
// not mirrors. This condition verifies that
// structures of tree are mirrors of each other.
if (!(root1 == null && root2 == null))
return false;
if (!st1.isEmpty() && !st2.isEmpty())
{
root1 = st1.peek();
root2 = st2.peek();
st1.pop();
st2.pop();
/* we have visited the node and its left subtree.
Now, it's right subtree's turn */
root1 = root1.right;
/* we have visited the node and its right subtree.
Now, it's left subtree's turn */
root2 = root2.left;
}
// both the trees have been completely traversed
else
break;
}
// tress are mirrors of each other
return true;
}
public boolean isSame(Node root1, Node root2)
{
// Return true if both trees are empty
if (root1 == null && root2 == null) return true;
// Return false if one is empty and other is not
if (root1 == null || root2 == null) return false;
// Create an empty queues for simultaneous traversals
Queue<Node > q1 = new LinkedList<Node> ();
Queue<Node> q2 = new LinkedList<Node> ();
// Enqueue Roots of trees in respective queues
q1.add(root1);
q2.add(root2);
while (!q1.isEmpty() && !q2.isEmpty())
{
// Get front nodes and compare them
Node n1 = q1.peek();
Node n2 = q2.peek();
if (n1.data != n2.data)
return false;
// Remove front nodes from queues
q1.remove();
q2.remove();
/* Enqueue left children of both nodes */
if (n1.left != null && n2.left != null)
{
q1.add(n1.left);
q2.add(n2.left);
}
// If one left child is empty and other is not
else if (n1.left != null || n2.left != null)
return false;
// Right child code (Similar to left child code)
if (n1.right != null && n2.right != null)
{
q1.add(n1.right);
q2.add(n2.right);
}
else if (n1.right != null || n2.right != null)
return false;
}
return true;
}
}
I hope this answer is helpful to you, please upvote my answer. I'm in need of it.. Thank you..