I am struggling to understand how to implement a remove(); for both a double and single linked class. I have figured out how to remove the first node in the double, but not in the single. First I would like to debug, problem solve the single linked class, then work on the double after that.
Here is the code I have so far for the Single Linked Class.
public class SingleLinkedClass<T> {
private Node <T> head;
private Node <T> tail;
private int size;
public SingleLinkedClass() {
size = 0;
head = null;
tail = null;
}
public void insertAtHead(T v)
{
//Allocate new node
Node newNode = new Node(v, head);
//Change head to point to new node
head = newNode;
if(tail == null)
{
tail = head;
}
//Increase size
size++;
}
public void insertAtTail(T v)
{
if(tail == null)
{
tail = new Node(v, null);
head = tail;
size++;
return;
}
Node newNode = new Node(v, null);
tail.nextNode = newNode;
tail = newNode;
size++;
}
public T removeHead()
{
if(head == null)
{
throw new IllegalStateException("list is empty! cannot delete");
}
T value = head.value;
head = head.nextNode;
size--;
return value;
}
public void removeTail()
{
//Case 1: list empty
if(head == null)
{
return;
}
//Case 2: list has one node
else if(head == tail)
{
head = tail = null;
}
else
{
Node temp = head;
while(temp.nextNode != tail)
{
temp = temp.nextNode;
}
tail = temp;
tail.nextNode = null;
}
size--;
}
public boolean remove(T v) {
Node<T> previous = head;
Node<T> cursor = head.nextNode;
if (head.nextNode == null) {
return false;
}
while(cursor != tail){
if (cursor.value.equals(v)) {
previous = cursor.nextNode;
return true;
}
previous = cursor;
cursor = cursor.nextNode;
}
return false;
}
public String toString() {
if (head == null) {
return "The list is Empty!";
}
String result = "";
Node temp = head;
while (temp != null) {
result += temp.toString() + " ";
temp = temp.nextNode;
}
return result;
}
public int size() {
return size;
}
private class Node <T> {
private T value;
private Node <T> nextNode;
public Node(T v, Node<T> n) {
value = v;
nextNode = n;
}
public String toString() {
return "" + value;
}
}
}
Here is my Double Linked Class
public class DoubelyLinkedList<E> {
private int size;
private Node<E> header;
private Node<E> trailer;
public DoubelyLinkedList() {
size = 0;
header = new Node<E>(null, null, null);
trailer = new Node<E>(null, null, header);
header.next = trailer;
}
public boolean remove(E v) {
//If the list is empty return false
if(header.next == trailer){
return false;
}
//If v is the head of the list remove and return true
Node <E> cursor = header.next;
for (int i = 0; i < size; i++) {
//Remove at Head
if(cursor.value.equals(v)){
removeAtHead();
}
cursor = cursor.next;
}
return true;
}
/*
} */
public void insertAtHead(E v) {
insertBetween(v, header, header.next);
}
public void insertAtTail(E v) {
insertBetween(v, trailer.prev, trailer);
}
private void insertBetween(E v, Node<E> first, Node<E> second) {
Node<E> newNode = new Node<>(v, second, first);
first.next = newNode;
second.prev = newNode;
size++;
}
public E removeAtHead() {
return removeBetween(header, header.next.next);
}
public E removeAtTail() {
return removeBetween(trailer.prev.prev, trailer);
}
private E removeBetween(Node<E> first, Node<E> second) {
if (header.next == trailer)// if the list is empty
{
throw new IllegalStateException("The list is empty!");
}
E result = first.next.value;
first.next = second;
second.prev = first;
size--;
return result;
}
public String toStringBackward() {
if (size == 0) {
return "The list is empty!";
}
String r = "";
Node<E> temp = trailer.prev;
while (temp != header) {
r += temp.toString() + " ";
temp = temp.prev;
}
return r;
}
public String toString() {
if (size == 0) {
return "The list is empty!";
}
String r = "";
Node<E> temp = header.next;
while (temp != trailer) {
r += temp + " ";
temp = temp.next;
}
return r;
}
private static class Node<T> {
private T value;
private Node<T> next;
private Node<T> prev;
public Node(T v, Node<T> n, Node<T> p) {
value = v;
next = n;
prev = p;
}
public String toString() {
return value.toString();
}
}
}
Here is my Driver
public class Driver {
public static void main(String[] args) {
DoubelyLinkedList<String> doubley = new DoubelyLinkedList();
SingleLinkedClass<String> single = new SingleLinkedClass();
single.insertAtHead("Bob");
single.insertAtHead("Sam");
single.insertAtHead("Terry");
single.insertAtHead("Don");
System.out.println(single);
single.remove("Bob");
System.out.println("Single Remove Head: " + single);
/*
single.remove("Don");
System.out.println("Single Remove Tail: " + single);
single.remove("Terry");
System.out.println("Single Remove Inbetween: " + single);
*/
System.out.println();
System.out.println();
doubley.insertAtHead("Bob");
doubley.insertAtHead("Sam");
doubley.insertAtHead("Terry");
doubley.insertAtHead("Don");
System.out.println(doubley);
doubley.remove("Bob");
System.out.println("Double Remove Head: " + doubley);
doubley.remove("Don");
System.out.println("Double Remove Tail: " + doubley);
/*
doubley.remove("Sam");
System.out.println("Double Remove Inbetween: " + doubley);
*/
}
}
In the removeHead moving head to its next, it might become null. Then tail was the head too. Then tail should be set to null too.
DoublyLinkedList is better English than DoubelyLinkedList.
As this is homework, I leave it by this.
I am having problem with sorting patient list based on seriousness and arrival time. Can take a look what wrong with my code? See the LList.java, the SortPatient method is correct?
ListInterface.java
public interface ListInterface<T> {
public boolean add(T newEntry);
public boolean add(int newPosition, T newEntry);
public T remove(int givenPosition);
public void clear();
public boolean replace(int givenPosition, T newEntry);
public T getEntry(int givenPosition);
public boolean contains(T anEntry);
public int getLength();
public boolean isEmpty();
public boolean isFull();
public int getPosition(T anObject);
public void SortPatient(ListInterface<Patient> patientList);
}
Llist.java
import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
public class LList<T> implements ListInterface<T> {
private Node firstNode; // reference to first node
private int length; // number of entries in list
public LList() {
clear();
}
public LList(T[] arr) {
clear();
firstNode = new Node(arr[0], null);
Node p = firstNode;
for (int index = 1; index < arr.length; index++) {
p.next = new Node(arr[index], null);
p = p.next;
//index must start with 0
//or add(arr[index]);
}
length = arr.length;
}
public int getPosition(T anObject) {
Node currentNode = firstNode;
int position = 0;
while (currentNode != null) {
position++;
if (currentNode.data.equals(anObject)) {
return position;
}
currentNode = currentNode.next;
}
return -1;
}
public final void clear() {
firstNode = null;
length = 0;
}
public boolean add(T newEntry) {
Node newNode = new Node(newEntry);
// create the new node
if (isEmpty()) // if empty list
{
firstNode = newNode;
} else { // add to end of nonempty list
Node currentNode = firstNode; // traverse linked list with p pointing to the current node
while (currentNode.next != null) { // while have not reached the last node
currentNode = currentNode.next;
}
currentNode.next = newNode; // make last node reference new node
}
length++;
return true;
}
public boolean add(int newPosition, T newEntry) { // OutOfMemoryError possible
boolean isSuccessful = true;
if ((newPosition >= 1) && (newPosition <= length + 1)) {
Node newNode = new Node(newEntry);
if (isEmpty() || (newPosition == 1)) { // case 1: add to beginning of list
newNode.next = firstNode;
firstNode = newNode;
} else { // case 2: list is not empty and newPosition > 1
Node nodeBefore = firstNode;
for (int i = 1; i < newPosition - 1; ++i) {
nodeBefore = nodeBefore.next; // advance nodeBefore to its next node
}
newNode.next = nodeBefore.next; // make new node point to current node at newPosition
nodeBefore.next = newNode; // make the node before point to the new node
}
length++;
} else {
isSuccessful = false;
}
return isSuccessful;
}
public T remove(int givenPosition) {
T result = null; // return value
if ((givenPosition >= 1) && (givenPosition <= length)) {
if (givenPosition == 1) { // case 1: remove first entry
result = firstNode.data; // save entry to be removed
firstNode = firstNode.next;
} else { // case 2: givenPosition > 1
Node nodeBefore = firstNode;
for (int i = 1; i < givenPosition - 1; ++i) {
nodeBefore = nodeBefore.next; // advance nodeBefore to its next node
}
result = nodeBefore.next.data; // save entry to be removed
nodeBefore.next = nodeBefore.next.next; // make node before point to node after the
} // one to be deleted (to disconnect node from chain)
length--;
}
return result; // return removed entry, or
// null if operation fails
}
public boolean replace(int givenPosition, T newEntry) {
boolean isSuccessful = true;
if ((givenPosition >= 1) && (givenPosition <= length)) {
Node currentNode = firstNode;
for (int i = 0; i < givenPosition - 1; ++i) {
// System.out.println("Trace| currentNode.data = " + currentNode.data + "\t, i = " + i);
currentNode = currentNode.next; // advance currentNode to next node
}
currentNode.data = newEntry; // currentNode is pointing to the node at givenPosition
} else {
isSuccessful = false;
}
return isSuccessful;
}
public T getEntry(int givenPosition) {
T result = null;
if ((givenPosition >= 1) && (givenPosition <= length)) {
Node currentNode = firstNode;
for (int i = 0; i < givenPosition - 1; ++i) {
currentNode = currentNode.next; // advance currentNode to next node
}
result = currentNode.data; // currentNode is pointing to the node at givenPosition
}
return result;
}
public boolean contains(T anEntry) {
boolean found = false;
Node currentNode = firstNode;
while (!found && (currentNode != null)) {
if (anEntry.equals(currentNode.data)) {
found = true;
} else {
currentNode = currentNode.next;
}
}
return found;
}
public int getLength() {
return length;
}
public boolean isEmpty() {
boolean result;
if (length == 0) {
result = true;
} else {
result = false;
}
return result;
}
public boolean isFull() {
return false;
}
public String toString() {
String outputStr = "";
Node currentNode = firstNode;
while (currentNode != null) {
outputStr += currentNode.data;
currentNode = currentNode.next;
}
return outputStr;
}
private class Node {
private T data;
private Node next;
private Node(T data) {
this.data = data;
this.next = null;
}
private Node(T data, Node next) {
this.data = data;
this.next = next;
}
} // end Node
public void SortPatient(ListInterface<Patient> patientList) {
if (patientList == null) {
return;
}
boolean swapped;
Patient patient;
do {
swapped = false;
patient = head;
while (patientList.next != null) {
if (patient.compareTo(patientList.next) < 1) {
swap(patientList.current, patientList.next);
swapped = true;
}
patient = patientList.next;
}
} while (swapped);
}
}
Patient.java
import java.util.Date;
import java.util.Collections;
import java.util.LinkedList;
import java.util.List;
import static javafx.scene.input.KeyCode.T;
public class Patient implements Comparable<Patient> {
String patientId;
String patientName;
String patientGender;
String patientIcNumber;
String patientContactNumber;
Date date;
int seriousness;
static int count = 0;
public Patient() {
}
public Patient(String patientId, String patientName, String patientGender, String patientIcNumber, String patientContactNumber, Date date, int seriousness) {
this.patientId = patientId;
this.patientName = patientName;
this.patientGender = patientGender;
this.patientIcNumber = patientIcNumber;
this.patientContactNumber = patientContactNumber;
this.date = date;
this.seriousness = seriousness;
count++;
}
public String getPatientId() {
return patientId;
}
public void setPatientId(String patientId) {
this.patientId = patientId;
}
public String getPatientName() {
return patientName;
}
public void setPatientName(String patientName) {
this.patientName = patientName;
}
public String getPatientGender() {
return patientGender;
}
public void setPatientGender(String patientGender) {
this.patientGender = patientGender;
}
public String getPatientIcNumber() {
return patientIcNumber;
}
public void setPatientIcNumber(String patientIcNumber) {
this.patientIcNumber = patientIcNumber;
}
public String getPatientContactNumber() {
return patientContactNumber;
}
public void setPatientContactNumber(String patientContactNumber) {
this.patientContactNumber = patientContactNumber;
}
public Date getDate() {
return date;
}
public void setDate(Date date) {
this.date = date;
}
public int getSeriousness() {
return seriousness;
}
public void setSeriousness(int seriousness) {
this.seriousness = seriousness;
}
public int getCount() {
return count;
}
#Override
public String toString() {
return patientId + " " + patientName + " " + patientGender + " " + patientIcNumber + " " + patientContactNumber + " " + date + " " + seriousness + "\n";
}
#Override
public int compareTo(Patient t) {
int patientSeriouness = t.seriousness;
Date arrival = t.date;
if (this.seriousness == patientSeriouness) {
return this.date.compareTo(arrival);
} else {
return Integer.compare(this.seriousness, patientSeriouness);
}
}
}
Couple of issues in your code (I just went through add,getentry and sort method):
In getEntry method, Remember index always start with 0 and go after till length - 1, so you should change our method to:
public T getEntry(int givenPosition) {
T result = null;
if ((givenPosition >= 0) && (givenPosition < length)) {
Node currentNode = firstNode;
for (int i = 0; i < givenPosition; ++i) {
currentNode = currentNode.next; // advance currentNode to next node
}
result = currentNode.data; // currentNode is pointing to the node at givenPosition
}
return result;
}
Change your interface and class implementation to remove passing on the ListInterface reference and your implementation should look like:
public void SortPatient() {
if (firstNode == null) {
return;
}
boolean swapped;
Node patient;
do {
swapped = false;
patient = firstNode;
while (patient.next != null) {
if (patient.data.compareTo(patient.next.data) > 0) {
swap(patient, patient.next);
swapped = true;
}
patient = patient.next;
}
} while (swapped);
}
private void swap(Node patient, Node nextPatient) {
T temp = patient.data;
patient.data = nextPatient.data;
nextPatient.data = temp;
}
Your compare to method in Patient class needs some improvements and it should be as below:
#Override
public int compareTo(Patient t) {
int patientSeriouness = t.seriousness;
Date arrival = t.date;
if (this.seriousness == patientSeriouness) {
return this.date.compareTo(arrival);
} else {
return ((Integer)this.seriousness).compareTo(patientSeriouness);
}
}
Last but not the least, your class definition LList should take generics of type Comparable (As you are using compareTo method), so you need to mandate that and it should be defined as
public class LList<T extends Comparable<T>> implements ListInterface<T>
Trying to write a method that removes all instances of a value from a singly linked list, but it doesn't appear to be working.
I tried to accomodate for whether or not the head contains the value, but I'm not sure whether or not this is the correct way to do so:
public void remove (int value)
{
if (head.value == value)
{
head = head.next;
count--;
}
IntegerNode temp=head;
while (temp !=null)
{
if (temp.next != null)
{
if (temp.next.value == value)
{
temp.next = temp.next.next;
count--;
}
}
temp=temp.next;
}
}
Is there something apparent wrong with my code?
Here the implementation of linked list with add and remove methods with test.
public class ListDemo {
public static void main(String[] args) {
MyList list = new MyList();
list.addToEnd(1);
list.addToEnd(2);
list.addToEnd(3);
list.removeByValue(2);
list.removeByValue(3);
}
}
class MyList {
private IntegerNode head;
private int count = 0;
public void addToEnd(int value) {
if(head == null) {
head = new IntegerNode(value);
count = 1;
head.next = null;
return;
}
IntegerNode current = head;
while (current.next != null) {
current = current.next;
}
IntegerNode node = new IntegerNode(value);
node.next = null;
count++;
current.next = node;
}
public void removeByValue(int value) {
if (count == 0) {
return;
} else if (count == 1) {
if (head.value == value) {
count = 0;
head = null;
}
} else {
IntegerNode current = this.head;
IntegerNode next = current.next;
while (next != null) {
if (next.value == value) {
if (next.next == null) {
current.next = null;
count--;
return;
} else {
current.next = next.next;
count--;
}
}
next = next.next;
}
}
}
}
class IntegerNode {
IntegerNode(int value) {
this.value = value;
}
IntegerNode next;
int value;
}
here is different ways to delete from Linked list
public Node removeAtFront()
{
Node returnedNode = null;
if(rootNode !=null)
{
if(rootNode.next !=null)
{
Node pointer = rootNode;
returnedNode = rootNode;
pointer = null;
rootNode = rootNode.next;
}
else
{
Node pointer = rootNode;
returnedNode = rootNode;
pointer = null;
rootNode = rootNode.next;
System.out.println("removing the last node");
}
}else
{
System.out.println("the linkedlist is empty");
}
return returnedNode;
}
public Node removeAtBack()
{
Node returnedNode = null;
if(rootNode != null)
{
//Remove the commented line if you wish to keep 1 node as minimum in the linked list
//if(rootNode.next !=null)
//{
Node pointer = new students();
pointer = rootNode;
while(pointer.next.next !=null)
{
pointer=pointer.next;
}
returnedNode = pointer.next.next;
pointer.next.next = null;
pointer.next = null;
//}
//else
//{
// System.out.println("cant remove the last node because its the root node");
//}
}
else
{
System.out.println("the linkedlist is empty");
}
return returnedNode;
}
public Node removeNode(String name)
{
Node returnedNode = null;
if(rootNode !=null)
{
Node pointer = new students();
Node previous = new students();
pointer = rootNode;
while(pointer !=null)
{
if(pointer.name.equals(name))
{
previous.next = pointer.next;
returnedNode = pointer;
pointer = null;
break;
}
else
{
previous = pointer;
pointer = pointer.next;
}
}
}
else
{
System.out.println("the linkedlist is empty");
}
return returnedNode;
}
public boolean isEmpty() {
return rootNode == null;
}
You need to track where you have been in the list rather than where you are going. Like this:
public void remove (int value)
{
IntegerNode current = head;
while (current !=null)
{
if (current.value == value)
{
if (head == current)
{
head = current.next;
}
else
{
head.next = current.next;
}
count--;
}
current=current.next;
}
}
I'm writing a program that utilizes a binary search tree to store data. In a previous program (unrelated), I was able to implement a linked list using an implementation provided with Java SE6. Is there something similar for a binary search tree, or will I need to "start from scratch"?
You can use a TreeMap data structure. TreeMap is implemented as a red black tree, which is a self-balancing binary search tree.
According to Collections Framework Overview you have two balanced tree implementations:
TreeSet
TreeMap
Here is my simple binary search tree implementation in Java SE 1.8:
public class BSTNode
{
int data;
BSTNode parent;
BSTNode left;
BSTNode right;
public BSTNode(int data)
{
this.data = data;
this.left = null;
this.right = null;
this.parent = null;
}
public BSTNode()
{
}
}
public class BSTFunctions
{
BSTNode ROOT;
public BSTFunctions()
{
this.ROOT = null;
}
void insertNode(BSTNode node, int data)
{
if (node == null)
{
node = new BSTNode(data);
ROOT = node;
}
else if (data < node.data && node.left == null)
{
node.left = new BSTNode(data);
node.left.parent = node;
}
else if (data >= node.data && node.right == null)
{
node.right = new BSTNode(data);
node.right.parent = node;
}
else
{
if (data < node.data)
{
insertNode(node.left, data);
}
else
{
insertNode(node.right, data);
}
}
}
public boolean search(BSTNode node, int data)
{
if (node == null)
{
return false;
}
else if (node.data == data)
{
return true;
}
else
{
if (data < node.data)
{
return search(node.left, data);
}
else
{
return search(node.right, data);
}
}
}
public void printInOrder(BSTNode node)
{
if (node != null)
{
printInOrder(node.left);
System.out.print(node.data + " - ");
printInOrder(node.right);
}
}
public void printPostOrder(BSTNode node)
{
if (node != null)
{
printPostOrder(node.left);
printPostOrder(node.right);
System.out.print(node.data + " - ");
}
}
public void printPreOrder(BSTNode node)
{
if (node != null)
{
System.out.print(node.data + " - ");
printPreOrder(node.left);
printPreOrder(node.right);
}
}
public static void main(String[] args)
{
BSTFunctions f = new BSTFunctions();
/**
* Insert
*/
f.insertNode(f.ROOT, 20);
f.insertNode(f.ROOT, 5);
f.insertNode(f.ROOT, 25);
f.insertNode(f.ROOT, 3);
f.insertNode(f.ROOT, 7);
f.insertNode(f.ROOT, 27);
f.insertNode(f.ROOT, 24);
/**
* Print
*/
f.printInOrder(f.ROOT);
System.out.println("");
f.printPostOrder(f.ROOT);
System.out.println("");
f.printPreOrder(f.ROOT);
System.out.println("");
/**
* Search
*/
System.out.println(f.search(f.ROOT, 27) ? "Found" : "Not Found");
System.out.println(f.search(f.ROOT, 10) ? "Found" : "Not Found");
}
}
And the output is:
3 - 5 - 7 - 20 - 24 - 25 - 27 -
3 - 7 - 5 - 24 - 27 - 25 - 20 -
20 - 5 - 3 - 7 - 25 - 24 - 27 -
Found
Not Found
Here is a sample implementation:
import java.util.*;
public class MyBSTree<K,V> implements MyTree<K,V>{
private BSTNode<K,V> _root;
private int _size;
private Comparator<K> _comparator;
private int mod = 0;
public MyBSTree(Comparator<K> comparator){
_comparator = comparator;
}
public Node<K,V> root(){
return _root;
}
public int size(){
return _size;
}
public boolean containsKey(K key){
if(_root == null){
return false;
}
BSTNode<K,V> node = _root;
while (node != null){
int comparison = compare(key, node.key());
if(comparison == 0){
return true;
}else if(comparison <= 0){
node = node._left;
}else {
node = node._right;
}
}
return false;
}
private int compare(K k1, K k2){
if(_comparator != null){
return _comparator.compare(k1,k2);
}
else {
Comparable<K> comparable = (Comparable<K>)k1;
return comparable.compareTo(k2);
}
}
public V get(K key){
Node<K,V> node = node(key);
return node != null ? node.value() : null;
}
private BSTNode<K,V> node(K key){
if(_root != null){
BSTNode<K,V> node = _root;
while (node != null){
int comparison = compare(key, node.key());
if(comparison == 0){
return node;
}else if(comparison <= 0){
node = node._left;
}else {
node = node._right;
}
}
}
return null;
}
public void add(K key, V value){
if(key == null){
throw new IllegalArgumentException("key");
}
if(_root == null){
_root = new BSTNode<K, V>(key, value);
}
BSTNode<K,V> prev = null, curr = _root;
boolean lastChildLeft = false;
while(curr != null){
int comparison = compare(key, curr.key());
prev = curr;
if(comparison == 0){
curr._value = value;
return;
}else if(comparison < 0){
curr = curr._left;
lastChildLeft = true;
}
else{
curr = curr._right;
lastChildLeft = false;
}
}
mod++;
if(lastChildLeft){
prev._left = new BSTNode<K, V>(key, value);
}else {
prev._right = new BSTNode<K, V>(key, value);
}
}
private void removeNode(BSTNode<K,V> curr){
if(curr.left() == null && curr.right() == null){
if(curr == _root){
_root = null;
}else{
if(curr.isLeft()) curr._parent._left = null;
else curr._parent._right = null;
}
}
else if(curr._left == null && curr._right != null){
curr._key = curr._right._key;
curr._value = curr._right._value;
curr._left = curr._right._left;
curr._right = curr._right._right;
}
else if(curr._left != null && curr._right == null){
curr._key = curr._left._key;
curr._value = curr._left._value;
curr._right = curr._left._right;
curr._left = curr._left._left;
}
else { // both left & right exist
BSTNode<K,V> x = curr._left;
// find right-most node of left sub-tree
while (x._right != null){
x = x._right;
}
// move that to current
curr._key = x._key;
curr._value = x._value;
// delete duplicate data
removeNode(x);
}
}
public V remove(K key){
BSTNode<K,V> curr = _root;
V val = null;
while(curr != null){
int comparison = compare(key, curr.key());
if(comparison == 0){
val = curr._value;
removeNode(curr);
mod++;
break;
}else if(comparison < 0){
curr = curr._left;
}
else{
curr = curr._right;
}
}
return val;
}
public Iterator<MyTree.Node<K,V>> iterator(){
return new MyIterator();
}
private class MyIterator implements Iterator<Node<K,V>>{
int _startMod;
Stack<BSTNode<K,V>> _stack;
public MyIterator(){
_startMod = MyBSTree.this.mod;
_stack = new Stack<BSTNode<K, V>>();
BSTNode<K,V> node = MyBSTree.this._root;
while (node != null){
_stack.push(node);
node = node._left;
}
}
public void remove(){
throw new UnsupportedOperationException();
}
public boolean hasNext(){
if(MyBSTree.this.mod != _startMod){
throw new ConcurrentModificationException();
}
return !_stack.empty();
}
public Node<K,V> next(){
if(MyBSTree.this.mod != _startMod){
throw new ConcurrentModificationException();
}
if(!hasNext()){
throw new NoSuchElementException();
}
BSTNode<K,V> node = _stack.pop();
BSTNode<K,V> x = node._right;
while (x != null){
_stack.push(x);
x = x._left;
}
return node;
}
}
#Override
public String toString(){
if(_root == null) return "[]";
return _root.toString();
}
private static class BSTNode<K,V> implements Node<K,V>{
K _key;
V _value;
BSTNode<K,V> _left, _right, _parent;
public BSTNode(K key, V value){
if(key == null){
throw new IllegalArgumentException("key");
}
_key = key;
_value = value;
}
public K key(){
return _key;
}
public V value(){
return _value;
}
public Node<K,V> left(){
return _left;
}
public Node<K,V> right(){
return _right;
}
public Node<K,V> parent(){
return _parent;
}
boolean isLeft(){
if(_parent == null) return false;
return _parent._left == this;
}
boolean isRight(){
if(_parent == null) return false;
return _parent._right == this;
}
#Override
public boolean equals(Object o){
if(o == null){
return false;
}
try{
BSTNode<K,V> node = (BSTNode<K,V>)o;
return node._key.equals(_key) && ((_value == null && node._value == null) || (_value != null && _value.equals(node._value)));
}catch (ClassCastException ex){
return false;
}
}
#Override
public int hashCode(){
int hashCode = _key.hashCode();
if(_value != null){
hashCode ^= _value.hashCode();
}
return hashCode;
}
#Override
public String toString(){
String leftStr = _left != null ? _left.toString() : "";
String rightStr = _right != null ? _right.toString() : "";
return "["+leftStr+" "+_key+" "+rightStr+"]";
}
}
}
This program has a functions for
Add Node
Display BST(Inorder)
Find Element
Find Successor
class BNode{
int data;
BNode left, right;
public BNode(int data){
this.data = data;
this.left = null;
this.right = null;
}
}
public class BST {
static BNode root;
public int add(int value){
BNode newNode, current;
newNode = new BNode(value);
if(root == null){
root = newNode;
current = root;
}
else{
current = root;
while(current.left != null || current.right != null){
if(newNode.data < current.data){
if(current.left != null)
current = current.left;
else
break;
}
else{
if(current.right != null)
current = current.right;
else
break;
}
}
if(newNode.data < current.data)
current.left = newNode;
else
current.right = newNode;
}
return value;
}
public void inorder(BNode root){
if (root != null) {
inorder(root.left);
System.out.println(root.data);
inorder(root.right);
}
}
public boolean find(int value){
boolean flag = false;
BNode current;
current = root;
while(current!= null){
if(current.data == value){
flag = true;
break;
}
else if(current.data > value)
current = current.left;
else
current = current.right;
}
System.out.println("Is "+value+" present in tree? : "+flag);
return flag;
}
public void successor(int value){
BNode current;
current = root;
if(find(value)){
while(current.data != value){
if(value < current.data && current.left != null){
System.out.println("Node is: "+current.data);
current = current.left;
}
else if(value > current.data && current.right != null){
System.out.println("Node is: "+current.data);
current = current.right;
}
}
}
else
System.out.println(value+" Element is not present in tree");
}
public static void main(String[] args) {
BST b = new BST();
b.add(50);
b.add(30);
b.add(20);
b.add(40);
b.add(70);
b.add(60);
b.add(80);
b.add(90);
b.inorder(root);
b.find(30);
b.find(90);
b.find(100);
b.find(50);
b.successor(90);
System.out.println();
b.successor(70);
}
}
Here is the complete Implementation of Binary Search Tree In Java insert,search,countNodes,traversal,delete,empty,maximum & minimum node,find parent node,print all leaf node, get level,get height, get depth,print left view, mirror view
import java.util.NoSuchElementException;
import java.util.Scanner;
import org.junit.experimental.max.MaxCore;
class BSTNode {
BSTNode left = null;
BSTNode rigth = null;
int data = 0;
public BSTNode() {
super();
}
public BSTNode(int data) {
this.left = null;
this.rigth = null;
this.data = data;
}
#Override
public String toString() {
return "BSTNode [left=" + left + ", rigth=" + rigth + ", data=" + data + "]";
}
}
class BinarySearchTree {
BSTNode root = null;
public BinarySearchTree() {
}
public void insert(int data) {
BSTNode node = new BSTNode(data);
if (root == null) {
root = node;
return;
}
BSTNode currentNode = root;
BSTNode parentNode = null;
while (true) {
parentNode = currentNode;
if (currentNode.data == data)
throw new IllegalArgumentException("Duplicates nodes note allowed in Binary Search Tree");
if (currentNode.data > data) {
currentNode = currentNode.left;
if (currentNode == null) {
parentNode.left = node;
return;
}
} else {
currentNode = currentNode.rigth;
if (currentNode == null) {
parentNode.rigth = node;
return;
}
}
}
}
public int countNodes() {
return countNodes(root);
}
private int countNodes(BSTNode node) {
if (node == null) {
return 0;
} else {
int count = 1;
count += countNodes(node.left);
count += countNodes(node.rigth);
return count;
}
}
public boolean searchNode(int data) {
if (empty())
return empty();
return searchNode(data, root);
}
public boolean searchNode(int data, BSTNode node) {
if (node != null) {
if (node.data == data)
return true;
else if (node.data > data)
return searchNode(data, node.left);
else if (node.data < data)
return searchNode(data, node.rigth);
}
return false;
}
public boolean delete(int data) {
if (empty())
throw new NoSuchElementException("Tree is Empty");
BSTNode currentNode = root;
BSTNode parentNode = root;
boolean isLeftChild = false;
while (currentNode.data != data) {
parentNode = currentNode;
if (currentNode.data > data) {
isLeftChild = true;
currentNode = currentNode.left;
} else if (currentNode.data < data) {
isLeftChild = false;
currentNode = currentNode.rigth;
}
if (currentNode == null)
return false;
}
// CASE 1: node with no child
if (currentNode.left == null && currentNode.rigth == null) {
if (currentNode == root)
root = null;
if (isLeftChild)
parentNode.left = null;
else
parentNode.rigth = null;
}
// CASE 2: if node with only one child
else if (currentNode.left != null && currentNode.rigth == null) {
if (root == currentNode) {
root = currentNode.left;
}
if (isLeftChild)
parentNode.left = currentNode.left;
else
parentNode.rigth = currentNode.left;
} else if (currentNode.rigth != null && currentNode.left == null) {
if (root == currentNode)
root = currentNode.rigth;
if (isLeftChild)
parentNode.left = currentNode.rigth;
else
parentNode.rigth = currentNode.rigth;
}
// CASE 3: node with two child
else if (currentNode.left != null && currentNode.rigth != null) {
// Now we have to find minimum element in rigth sub tree
// that is called successor
BSTNode successor = getSuccessor(currentNode);
if (currentNode == root)
root = successor;
if (isLeftChild)
parentNode.left = successor;
else
parentNode.rigth = successor;
successor.left = currentNode.left;
}
return true;
}
private BSTNode getSuccessor(BSTNode deleteNode) {
BSTNode successor = null;
BSTNode parentSuccessor = null;
BSTNode currentNode = deleteNode.left;
while (currentNode != null) {
parentSuccessor = successor;
successor = currentNode;
currentNode = currentNode.left;
}
if (successor != deleteNode.rigth) {
parentSuccessor.left = successor.left;
successor.rigth = deleteNode.rigth;
}
return successor;
}
public int nodeWithMinimumValue() {
return nodeWithMinimumValue(root);
}
private int nodeWithMinimumValue(BSTNode node) {
if (node.left != null)
return nodeWithMinimumValue(node.left);
return node.data;
}
public int nodewithMaximumValue() {
return nodewithMaximumValue(root);
}
private int nodewithMaximumValue(BSTNode node) {
if (node.rigth != null)
return nodewithMaximumValue(node.rigth);
return node.data;
}
public int parent(int data) {
return parent(root, data);
}
private int parent(BSTNode node, int data) {
if (empty())
throw new IllegalArgumentException("Empty");
if (root.data == data)
throw new IllegalArgumentException("No Parent node found");
BSTNode parent = null;
BSTNode current = node;
while (current.data != data) {
parent = current;
if (current.data > data)
current = current.left;
else
current = current.rigth;
if (current == null)
throw new IllegalArgumentException(data + " is not a node in tree");
}
return parent.data;
}
public int sibling(int data) {
return sibling(root, data);
}
private int sibling(BSTNode node, int data) {
if (empty())
throw new IllegalArgumentException("Empty");
if (root.data == data)
throw new IllegalArgumentException("No Parent node found");
BSTNode cureent = node;
BSTNode parent = null;
boolean isLeft = false;
while (cureent.data != data) {
parent = cureent;
if (cureent.data > data) {
cureent = cureent.left;
isLeft = true;
} else {
cureent = cureent.rigth;
isLeft = false;
}
if (cureent == null)
throw new IllegalArgumentException("No Parent node found");
}
if (isLeft) {
if (parent.rigth != null) {
return parent.rigth.data;
} else
throw new IllegalArgumentException("No Sibling is there");
} else {
if (parent.left != null)
return parent.left.data;
else
throw new IllegalArgumentException("No Sibling is there");
}
}
public void leafNodes() {
if (empty())
throw new IllegalArgumentException("Empty");
leafNode(root);
}
private void leafNode(BSTNode node) {
if (node == null)
return;
if (node.rigth == null && node.left == null)
System.out.print(node.data + " ");
leafNode(node.left);
leafNode(node.rigth);
}
public int level(int data) {
if (empty())
throw new IllegalArgumentException("Empty");
return level(root, data, 1);
}
private int level(BSTNode node, int data, int level) {
if (node == null)
return 0;
if (node.data == data)
return level;
int result = level(node.left, data, level + 1);
if (result != 0)
return result;
result = level(node.rigth, data, level + 1);
return result;
}
public int depth() {
return depth(root);
}
private int depth(BSTNode node) {
if (node == null)
return 0;
else
return 1 + Math.max(depth(node.left), depth(node.rigth));
}
public int height() {
return height(root);
}
private int height(BSTNode node) {
if (node == null)
return 0;
else
return 1 + Math.max(height(node.left), height(node.rigth));
}
public void leftView() {
leftView(root);
}
private void leftView(BSTNode node) {
if (node == null)
return;
int height = height(node);
for (int i = 1; i <= height; i++) {
printLeftView(node, i);
}
}
private boolean printLeftView(BSTNode node, int level) {
if (node == null)
return false;
if (level == 1) {
System.out.print(node.data + " ");
return true;
} else {
boolean left = printLeftView(node.left, level - 1);
if (left)
return true;
else
return printLeftView(node.rigth, level - 1);
}
}
public void mirroeView() {
BSTNode node = mirroeView(root);
preorder(node);
System.out.println();
inorder(node);
System.out.println();
postorder(node);
System.out.println();
}
private BSTNode mirroeView(BSTNode node) {
if (node == null || (node.left == null && node.rigth == null))
return node;
BSTNode temp = node.left;
node.left = node.rigth;
node.rigth = temp;
mirroeView(node.left);
mirroeView(node.rigth);
return node;
}
public void preorder() {
preorder(root);
}
private void preorder(BSTNode node) {
if (node != null) {
System.out.print(node.data + " ");
preorder(node.left);
preorder(node.rigth);
}
}
public void inorder() {
inorder(root);
}
private void inorder(BSTNode node) {
if (node != null) {
inorder(node.left);
System.out.print(node.data + " ");
inorder(node.rigth);
}
}
public void postorder() {
postorder(root);
}
private void postorder(BSTNode node) {
if (node != null) {
postorder(node.left);
postorder(node.rigth);
System.out.print(node.data + " ");
}
}
public boolean empty() {
return root == null;
}
}
public class BinarySearchTreeTest {
public static void main(String[] l) {
System.out.println("Weleome to Binary Search Tree");
Scanner scanner = new Scanner(System.in);
boolean yes = true;
BinarySearchTree tree = new BinarySearchTree();
do {
System.out.println("\n1. Insert");
System.out.println("2. Search Node");
System.out.println("3. Count Node");
System.out.println("4. Empty Status");
System.out.println("5. Delete Node");
System.out.println("6. Node with Minimum Value");
System.out.println("7. Node with Maximum Value");
System.out.println("8. Find Parent node");
System.out.println("9. Count no of links");
System.out.println("10. Get the sibling of any node");
System.out.println("11. Print all the leaf node");
System.out.println("12. Get the level of node");
System.out.println("13. Depth of the tree");
System.out.println("14. Height of Binary Tree");
System.out.println("15. Left View");
System.out.println("16. Mirror Image of Binary Tree");
System.out.println("Enter Your Choice :: ");
int choice = scanner.nextInt();
switch (choice) {
case 1:
try {
System.out.println("Enter Value");
tree.insert(scanner.nextInt());
} catch (Exception e) {
System.out.println(e.getMessage());
}
break;
case 2:
System.out.println("Enter the node");
System.out.println(tree.searchNode(scanner.nextInt()));
break;
case 3:
System.out.println(tree.countNodes());
break;
case 4:
System.out.println(tree.empty());
break;
case 5:
try {
System.out.println("Enter the node");
System.out.println(tree.delete(scanner.nextInt()));
} catch (Exception e) {
System.out.println(e.getMessage());
}
case 6:
try {
System.out.println(tree.nodeWithMinimumValue());
} catch (Exception e) {
System.out.println(e.getMessage());
}
break;
case 7:
try {
System.out.println(tree.nodewithMaximumValue());
} catch (Exception e) {
System.out.println(e.getMessage());
}
break;
case 8:
try {
System.out.println("Enter the node");
System.out.println(tree.parent(scanner.nextInt()));
} catch (Exception e) {
System.out.println(e.getMessage());
}
break;
case 9:
try {
System.out.println(tree.countNodes() - 1);
} catch (Exception e) {
System.out.println(e.getMessage());
}
break;
case 10:
try {
System.out.println("Enter the node");
System.out.println(tree.sibling(scanner.nextInt()));
} catch (Exception e) {
System.out.println(e.getMessage());
}
break;
case 11:
try {
tree.leafNodes();
} catch (Exception e) {
System.out.println(e.getMessage());
}
case 12:
try {
System.out.println("Enter the node");
System.out.println("Level is : " + tree.level(scanner.nextInt()));
} catch (Exception e) {
System.out.println(e.getMessage());
}
break;
case 13:
try {
System.out.println(tree.depth());
} catch (Exception e) {
System.out.println(e.getMessage());
}
break;
case 14:
try {
System.out.println(tree.height());
} catch (Exception e) {
System.out.println(e.getMessage());
}
break;
case 15:
try {
tree.leftView();
System.out.println();
} catch (Exception e) {
System.out.println(e.getMessage());
}
break;
case 16:
try {
tree.mirroeView();
} catch (Exception e) {
System.out.println(e.getMessage());
}
break;
default:
break;
}
tree.preorder();
System.out.println();
tree.inorder();
System.out.println();
tree.postorder();
} while (yes);
scanner.close();
}
}
I am trying to do a an avl tree which updates itself everytime the tree is unbalanced. The rotations are working but i have a bug where if for example the tree node 7, leftChild 6 , leftchild of leftchild 5 becomes node 6, leftchild 5, rightchild 7, and after balancing I add a new node, the node is first compared with 7 and not with 6. How do I fix this problem?
This is the main class:
import java.io.*;
import javax.swing.*;
import java.util.*;
import java.lang.*;
public class NewMain implements Cloneable{
/**
* #param args the command line arguments
*/
public static void main(String[] args)
{
File file = new File ("AVLTree.txt");
ArrayList <TreeNode> array = new ArrayList ();
Scanner kb = new Scanner (System.in);
int num = 0;
TreeNode root = new TreeNode ();
do {
System.out.print(" AVL Tree \n\n\n\n");
System.out.println("1. Create a new binary tree");
System.out.println("2. Save Tree");
System.out.println("3. Load Tree");
System.out.println("4. Enter a new node in the tree");
System.out.println("5. Show current AVL tree");
System.out.println("6. Show inorder traversal");
System.out.println("7. Search");
System.out.println("8. Quit \n\n\n\n\n\n\n");
System.out.print("Enter a number: ");
num = kb.nextInt ();
if (num == 1){
if (array.isEmpty ())
{
System.out.print ("Enter the root value: ");
int value = kb.nextInt ();
root = new TreeNode();
root.setValue(value);
array.add(root);
}
else
{
array.clear();
System.out.print ("Enter the root value: ");
int value = kb.nextInt ();
root = new TreeNode();
root.setValue(value);
array.add(root);
}
}
if (num == 2)
{
FileOutputStream outFile = null;
ObjectOutputStream oos = null;
try
{
outFile = new FileOutputStream(file);
oos = new ObjectOutputStream(outFile);
for (TreeNode list : array)
{
oos.writeObject(list);
}
oos.close();
}
catch (Exception e)
{
System.out.print("Save Not Successful!");
}
}
if (num == 3)
{
if (file.exists())
{
FileInputStream inFile = null;
ObjectInputStream ios = null;
try
{
Object obj = null;
inFile = new FileInputStream(file);
ios = new ObjectInputStream(inFile);
while ((obj = ios.readObject()) != null) {
if (obj instanceof TreeNode)
{
array.add((TreeNode) obj);
}
}
ios.close();
}
catch(EOFException e)
{
}
catch (Exception e)
{
System.out.print("File was not found while loading");
}
}
}
if (num == 4)
{
System.out.print ("Enter a new child node: ");
int value = kb.nextInt ();
try
{
array.add(root.insert(value));
root.balance();
}
catch (Exception e)
{
System.out.print (e.getMessage());
}
}
if (num == 5){
System.out.print ("Pointer Number\t\tLeft\t\tNode\t\tRight\t\tLeft Height\t\tRight Height\n");
for (int i=0; i<array.size();i++)
{
System.out.print (i+"\t\t\t"+array.indexOf(array.get(i).getLeftChild())+"\t\t"+array.get(i).getValue()+"\t\t"+array.indexOf(array.get(i).getRightChild())+"\t\t"+array.get(i).getLeftHeight()+"\t\t\t"+array.get(i).getRightHeight()+"\n");
}
}
if (num == 6)
{
System.out.print("Inorder traversal: ");
System.out.println(root.InOrderTraversal());
System.out.print("Postorder traversal: ");
System.out.println(root.PostOrderTraversal());
System.out.print("Preorder traversal: ");
System.out.println(root.PreOrderTraversal());
}
if (num == 7)
{
System.out.print("Enter node to be searched: ");
int node = kb.nextInt ();
for (int i = 0; i<array.size();i++)
{
if (node == array.get(i).getValue())
{
System.out.print ("Node is in index "+i+"\n");
break;
}
if (i == array.size()-1 && node != array.get(i).getValue())
{
System.out.print ("Node not found in the tree!"+"\n");
break;
}
}
}
}while (num != 8);
}
}
This is from a normal java class:
import java.lang.StringBuilder;
import java.util.ArrayList;
import java.io.*;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.*;
public class TreeNode implements Serializable, Cloneable
{
public Integer value;
public TreeNode leftChild;
public TreeNode rightChild;
public TreeNode()
{
this.value = null;
this.leftChild = null;
this.rightChild = null;
}
public TreeNode(int value)
{
this.value = value;
this.leftChild = null;
this.rightChild = null;
}
public int getValue()
{
return this.value;
}
public void setValue(int value)
{
this.value = value;
}
public TreeNode getLeftChild()
{
return this.leftChild;
}
public void setLeftChild(TreeNode leftChild)
{
this.leftChild = leftChild;
}
public TreeNode getRightChild()
{
return this.rightChild;
}
public void setRightChild(TreeNode rightChild)
{
this.rightChild = rightChild;
}
public int getLeftHeight()
{
if (this.leftChild == null)
{
return 0;
}
else
{
return this.getLeftChild().getHeight() + 1;
}
}
public int getRightHeight()
{
if (this.rightChild == null)
{
return 0;
}
else
{
return this.getRightChild().getHeight() + 1;
}
}
public TreeNode insert(int value) throws Exception
{
if(this.value == null && this.leftChild == null && this.rightChild == null)
{
this.value = value;
return this;
}
else
{
TreeNode node = new TreeNode (value);
if(value < this.value)
{
if(this.getLeftChild() == null)
{
this.setLeftChild (node);
return node;
}
else
{
return this.getLeftChild().insert(value);
}
}
else if(value > this.value)
{
if(this.getRightChild() == null)
{
this.setRightChild(node);
return node;
}
else
{
return this.getRightChild().insert(value);
}
}
else
{
return null;
}
}
}
public TreeNode balance() throws Exception
{
if (Math.abs(this.getLeftHeight() - this.getRightHeight())==2)
{
if (this.rightChild == null)
{
if(this.leftChild.leftChild != null)
{
return this.LLRotation ();
}
if(this.leftChild.rightChild != null)
{
return this.LRRotation ();
}
}
if (this.leftChild == null)
{
if (this.rightChild.rightChild != null)
{
return this.RRRotation ();
}
if (this.rightChild.leftChild != null)
{
return this.RLRotation ();
}
}
}
else
{
if (this.getLeftChild () != null)
{
return this.getLeftChild().balance();
}
if (this.getRightChild () != null)
{
return this.getRightChild().balance();
}
}
return this;
}
public int getHeight ()
{
if (this.leftChild == null && this.rightChild == null)
{
return 0;
}
else
{
int leftH = 0;
int rightH = 0;
if (this.leftChild != null)
{
leftH++;
leftH += this.getLeftChild().getHeight();
}
if (this.rightChild != null)
{
rightH++;
rightH += this.getRightChild().getHeight();
}
return Math.max(leftH,rightH);
}
}
public TreeNode LLRotation ()
{
TreeNode temp = this.leftChild;
this.leftChild = null;
temp.rightChild = this;
return temp;
}
public TreeNode RRRotation ()
{
TreeNode temp = this.rightChild;
this.rightChild = temp.leftChild;
try
{
temp.leftChild = (TreeNode)this.clone();
}
catch (CloneNotSupportedException ex)
{
}
this.value = temp.value;
this.rightChild = temp.rightChild;
this.leftChild = temp.leftChild;
return temp;
}
public TreeNode LRRotation ()
{
this.leftChild = this.leftChild.RRRotation();
return LLRotation();
}
public TreeNode RLRotation ()
{
this.rightChild = this.rightChild.RRRotation();
return RRRotation();
}
public String InOrderTraversal ()
{
StringBuilder sb = new StringBuilder ();
if (this.leftChild == null && this.rightChild == null)
{
sb.append(this.value).append(" ");
}
else
{
if(this.leftChild != null)
{
sb.append(this.getLeftChild().InOrderTraversal());
}
sb.append(this.value).append(" ");
if (this.rightChild != null)
{
sb.append(this.getRightChild().InOrderTraversal());
}
}
return sb.toString();
}
public String PostOrderTraversal ()
{
StringBuilder sb = new StringBuilder ();
if (this.leftChild == null && this.rightChild == null)
{
sb.append(this.value).append(" ");
}
else
{
if(this.leftChild != null)
{
sb.append(this.getLeftChild().PostOrderTraversal());
}
if (this.rightChild != null)
{
sb.append(this.getRightChild().PostOrderTraversal());
}
sb.append(this.value).append(" ");
}
return sb.toString();
}
public String PreOrderTraversal ()
{
StringBuilder sb = new StringBuilder ();
if (this.leftChild == null && this.rightChild == null)
{
sb.append(this.value).append(" ");
}
else
{
sb.append(this.value).append(" ");
if(this.leftChild != null)
{
sb.append(this.getLeftChild().PreOrderTraversal());
}
if (this.rightChild != null)
{
sb.append(this.getRightChild().PreOrderTraversal());
}
}
return sb.toString();
}
}
The code is a bit more complex it needs to be. I hope here to give you a simpler version, which with you yourself may correctly balance. As maybe you should better do pointer rotation / rebalancing inside the insertion. Don't feel obliged to give points; this is but a half answer.
Remark only: the field value may be an ìnt.
It is definitely easier for recursive algorithms, if the "this" object might be null. This can be achieved by wrapping the entire tree in one public class, which uses the TreeNode class internally.
public class Tree {
private static class TreeNode {
private int value;
private TreeNode left;
private TreeNode right;
private TreeNode(int value, TreeNode left, TreeNode right) {
this.value = value;
this.left = left;
this.right = right;
}
}
private static class AlreadyExistsException extends Exception {
private TreeNode node;
private AlreadyExistsException(TreeNode node) {
this.node = node;
}
public TreeNode getNode() {
return node;
}
}
private TreeNode root;
private int size;
public boolean insert(int value) {
try {
root = insertInto(root, value);
++size;
return true;
} catch (AlreadyExistsException e) {
// Fine.
return false;
}
}
private TreeNode insertInto(TreeNode node, int value) throws AlreadyExistsException {
if (node == null) {
return new TreeNode(value, null, null);
}
if (value < node.value) {
node.left = insertInto(node.left, value);
return node;
} else if (value > node.value) {
node.right = insertInto(node.right, value);
return node;
} else {
throw new AlreadyExistsException(node);
}
}
}
As you see the for balancing immediately during the insertion, there could be done an insertion with pointer rotation at < and > (3 pointers: left's right-most leaf or right's left-most leaf). Comming back from recursion one could have collected the parent of the left's right-most leaf, and perform a rotation. Or at any other point. There exist 3 variants!
Probably because root is still pointing at the old node. Are you sure you want to ignore the return value of balance() at the marked line?
if (num == 4) {
System.out.print ("Enter a new child node: ");
int value = kb.nextInt ();
try {
array.add(root.insert(value));
root.balance(); // look here
} catch (Exception e) {
System.out.print (e.getMessage());
}
}
BTW, an AVL tree as described in the literature does not recurse of the entirety of the tree to find the balance of a node.