linked list implementation java - java

I have implemented a Linked List into Java. I have created everything, but I am having difficulty removing a specific node with specific data. It is throwing a NullPointerException. I believe, I am getting a NullPointerException because the next node is null. If someone could please point me in the right direction that would be great.
Input
anything
one
two
three
exception:
Exception in thread "main" java.lang.NullPointerException
at LinkedList.remove(LinkedList.java:28)
at Main.main(Main.java:29)
Classes:
Linked list class
public class LinkedList {
// fields
private Node head;
private Node last;
private int size = 0;
// constructor, used when the class is first called
public LinkedList() {
head = last = new Node(null);
}
// add method
public void add(String s) {
last.setNext(new Node(s));
last = last.getNext();
size++;
}
// remove method, if it returns false then the specified index element doens not exist
// otherwise will return true
public boolean remove(String data) {
Node current = head;
last = null;
while(current != null) {
if(current.getData().equals(data)) {
current = current.getNext();
if(last == null) {
last = current;
}else {
last.getNext().setNext(current);
size--;
return true;
}
}else {
last = current;
current = current.getNext();
}
}
return false;
}
//will return the size of the list - will return -1 if list is empty
public int size() {
return size;
}
// will check if the list is empty or not
public boolean isEmpty() {
return true;
}
// #param (index) will get the data at specified index
public String getData(int index) {
if(index <= 0) {
return null;
}
Node current = head.getNext();
for(int i = 1;i < index;i++) {
if(current.getNext() == null) {
return null;
}
current = current.getNext();
}
return current.getData();
}
//#param will check if the arguement passed is in the list
// will return true if the list contains arg otherwise false
public boolean contains(String s) {
for(int i = 1;i<=size();i++) {
if(getData(i).equals(s)) {
return true;
}
}
return false;
}
//#return contents of the list - recursively
public String toString() {
Node current = head.getNext();
String output = "[";
while(current != null) {
output += current.getData()+",";
current = current.getNext();
}
return output+"]";
}
//#return first node
public Node getHead() {
return head;
}
// #return (recursively) list
public void print(Node n) {
if(n == null) {
return;
}else {
System.out.println(n.getData());
print(n.getNext());
}
}
}
Main
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
public class Main {
static BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
public static void main(String[] args) throws IOException{
LinkedList list = new LinkedList(); // declaring main linked list
LinkedList b_List = new LinkedList(); // declaring the backup list
String input = null;
// getting input from user, will stop when user has entered 'fin'
while(!(input = br.readLine()).equals("fin")) {
list.add(input); // adding to main list
b_List.add(input);
}
list.print(list.getHead().getNext());
System.out.println("Input Complete.");
if(list.size() == 1) {
System.out.println("You have entered only one name. He/She is the survior");
}else {
System.out.println("Enter the name(s) would like to remove: ");
while(b_List.size() != 1) {
String toRemove = br.readLine();
b_List.remove(toRemove);
}
}
System.out.println("The contestants were: ");
list.print(list.getHead().getNext());
}
}
node
public class Node {
// Fields
private String data;
private Node next;
// constructor
public Node(String data) {
this(data,null);
}
// constructor two with Node parameter
public Node(String data, Node node) {
this.data = data;
next = node;
}
/**
* Methods below return information about fields within class
* */
// #return the data
public String getData() {
return data;
}
// #param String data to this.data
public void setData(String data) {
this.data = data;
}
// #return next
public Node getNext() {
return next;
}
// #param Node next set to this.next
public void setNext(Node next) {
this.next = next;
}
}

First of all, your head is just a before-first marker so you shouldn't start the remove check from it.
Second, your remove method fails if node data is null
Third - your implementation is broken anyway because of last.getNext().setNext(current) - it won't link previous node with next, it will link current to next (i.e. will do nothing)
Fourth - it still fails to remove first element because of mysterious operations with last...
Correct implementation of remove would be something like this:
public boolean remove(String data){
Node previous = head;
Node current = head.getNext();
while (current != null) {
String dataOld = current.getData();
if ((dataOld == null && data == null) || (dataOld != null && dataOld.equals(data))) {
Node afterRemoved = current.getNext();
previous.setNext(afterRemoved);
if (afterRemoved == null) { // i.e. removing last element
last = previous;
}
size--;
return true;
} else {
previous = current;
current = current.getNext();
}
}
return false;
}

Here we can see the simple implementation of LinkedList with iterator
class LinkedList implements Iterable{
private Node node;
public void add(Object data){
if(!Optional.ofNullable(node).isPresent()){
node = new Node();
node.setData(data);
}else{
Node node = new Node();
node.setData(data);
Node lastNode = getLastNode(this.node);
lastNode.setNext(node);
}
}
private Node getLastNode(Node node){
if(node.getNext()==null){
return node;
}else{
return getLastNode(node.getNext());
}
}
class Node{
private Object data;
private Node next;
public Object getData() {
return data;
}
public void setData(Object data) {
this.data = data;
}
public Node getNext() {
return next;
}
public void setNext(Node next) {
this.next = next;
}
}
public Iterator iterator() {
return new NodeIterator();
}
class NodeIterator implements Iterator{
private Node current;
public boolean hasNext() {
if(current == null){
current = node;
return Optional.ofNullable(current).isPresent();
}else{
current = current.next;
return Optional.ofNullable(current).isPresent();
}
}
public Node next() {
return current;
}
}
}
public class LinkedListImpl {
public static void main(String[] args) {
LinkedList linkedList = new LinkedList();
linkedList.add("data1");
linkedList.add("data2");
linkedList.add("data3");
for(LinkedList.Node node: linkedList){
System.out.println(node.getData());
}
}
}

Here is Full Implementaion of Linked List
including insertion,deletion,searching,reversing,swaping,size,display and various important operations of linked list
import java.util.NoSuchElementException;
import java.util.Scanner;
class Node<T> {
public Node<T> next;
public T data;
public Node() {
}
public Node(T data, Node<T> next) {
this.data = data;
this.next = next;
}
#Override
public String toString() {
return "Node [next=" + next + ", data=" + data + "]";
}
}
class LinkedList<T> {
Node<T> start = null;
Node<T> end = null;
public void insertAtStart(T data) {
Node<T> nptr = new Node<T>(data, null);
if (empty()) {
start = nptr;
end = start;
} else {
nptr.next = start;
start = nptr;
}
display();
}
public void insertAtEnd(T data) {
Node<T> nptr = new Node<T>(data, null);
if (empty()) {
insertAtStart(data);
return;
} else {
end.next = nptr;
end = nptr;
}
display();
}
public void insertAtPosition(int position, T data) {
if (position != 1 && empty())
throw new IllegalArgumentException("Empty");
if (position == 1) {
insertAtStart(data);
return;
}
Node<T> nptr = new Node<T>(data, null);
if (position == size()) {
Node<T> startPtr = start;
Node<T> endPtr = startPtr;
while (startPtr.next != null) {
endPtr = startPtr;
startPtr = startPtr.next;
}
endPtr.next = nptr;
nptr.next = end;
} else {
position -= 1;
Node<T> startPtr = start;
for (int i = 1; i < size(); i++) {
if (i == position) {
Node<T> temp = startPtr.next;
startPtr.next = nptr;
nptr.next = temp;
}
startPtr = startPtr.next;
}
}
display();
}
public void delete(int position) {
if (empty())
throw new IllegalArgumentException("Empty");
if (position == 1) {
start = start.next;
} else if (position == size()) {
Node<T> startPtr = start;
Node<T> endPtr = start;
while (startPtr.next != null) {
endPtr = startPtr;
startPtr = startPtr.next;
}
endPtr.next = null;
end = endPtr;
} else {
position -= 1;
Node<T> startPtr = start;
for (int i = 1; i <= position; i++) {
if (i == position) {
Node<T> temp = startPtr.next.next;
startPtr.next = temp;
}
startPtr = startPtr.next;
}
}
display();
}
public int index(T data) {
if (empty())
throw new IllegalArgumentException("Empty");
return index(start, data, 0);
}
private int index(Node<T> link, T data, int index) {
if (link != null) {
if (link.data == data) {
return index;
}
return index(link.next, data, ++index);
}
return -1;
}
public void replace(int position, T data) {
if (empty())
throw new IllegalArgumentException("Empty");
if (position == 1)
start.data = data;
else if (position == size())
end.data = data;
else {
Node<T> startPtr = start;
for (int i = 1; i <= position; i++) {
if (i == position)
startPtr.data = data;
startPtr = startPtr.next;
}
}
display();
}
public void replaceRecursively(int position, T data) {
replaceRecursively(start, position, data, 1);
display();
}
private void replaceRecursively(Node<T> link, int position, T data, int count) {
if (link != null) {
if (count == position) {
link.data = data;
return;
}
replaceRecursively(link.next, position, data, ++count);
}
}
public T middle() {
if (empty())
throw new NoSuchElementException("Empty");
Node<T> slowPtr = start;
Node<T> fastPtr = start;
while (fastPtr != null && fastPtr.next != null) {
slowPtr = slowPtr.next;
fastPtr = fastPtr.next.next;
}
return slowPtr.data;
}
public int occurence(T data) {
if (empty())
throw new NoSuchElementException("Empty");
return occurence(start, data, 0);
}
private int occurence(Node<T> link, T data, int occurence) {
if (link != null) {
if (link.data == data)
++occurence;
return occurence(link.next, data, occurence);
}
return occurence;
}
public void reverseRecusively() {
reverseRecusively(start);
swapLink();
display();
}
private Node<T> reverseRecusively(Node<T> link) {
if (link == null || link.next == null)
return link;
Node<T> nextLink = link.next;
link.next = null;
Node<T> revrseList = reverseRecusively(nextLink);
nextLink.next = link;
return revrseList;
}
public void reverse() {
if (empty())
throw new NoSuchElementException("Empty");
Node<T> prevLink = null;
Node<T> currentLink = start;
Node<T> nextLink = null;
while (currentLink != null) {
nextLink = currentLink.next;
currentLink.next = prevLink;
prevLink = currentLink;
currentLink = nextLink;
}
swapLink();
display();
}
private void swapLink() {
Node<T> temp = start;
start = end;
end = temp;
}
public void swapNode(T dataOne, T dataTwo) {
if (dataOne == dataTwo)
throw new IllegalArgumentException("Can't swap " + dataOne + " and " + dataTwo + " both are same");
boolean foundDataOne = false;
boolean foundDataTwo = false;
Node<T> dataOnePtr = start;
Node<T> dataOnePrevPtr = start;
while (dataOnePtr.next != null && dataOnePtr.data != dataOne) {
dataOnePrevPtr = dataOnePtr;
dataOnePtr = dataOnePtr.next;
}
Node<T> dataTwoPtr = start;
Node<T> dataTwoPrevPtr = start;
while (dataTwoPtr.next != null && dataTwoPtr.data != dataTwo) {
dataTwoPrevPtr = dataTwoPtr;
dataTwoPtr = dataTwoPtr.next;
}
if (dataOnePtr != null && dataOnePtr.data == dataOne)
foundDataOne = true;
if (dataTwoPtr != null && dataTwoPtr.data == dataTwo)
foundDataTwo = true;
if (foundDataOne && foundDataTwo) {
if (dataOnePtr == start)
start = dataTwoPtr;
else if (dataTwoPtr == start)
start = dataOnePtr;
if (dataTwoPtr == end)
end = dataOnePtr;
else if (dataOnePtr == end)
end = dataTwoPtr;
Node<T> tempDataOnePtr = dataOnePtr.next;
Node<T> tempDataTwoPtr = dataTwoPtr.next;
dataOnePrevPtr.next = dataTwoPtr;
dataTwoPtr.next = tempDataOnePtr;
dataTwoPrevPtr.next = dataOnePtr;
dataOnePtr.next = tempDataTwoPtr;
if (dataOnePtr == dataTwoPrevPtr) {
dataTwoPtr.next = dataOnePtr;
dataOnePtr.next = tempDataTwoPtr;
} else if (dataTwoPtr == dataOnePrevPtr) {
dataOnePtr.next = dataTwoPtr;
dataTwoPtr.next = tempDataOnePtr;
}
} else
throw new NoSuchElementException("Either " + dataOne + " or " + dataTwo + " not in the list");
display();
}
public int size() {
return size(start, 0);
}
private int size(Node<T> link, int i) {
if (link == null)
return 0;
else {
int count = 1;
count += size(link.next, 0);
return count;
}
}
public void printNthNodeFromLast(int n) {
if (empty())
throw new NoSuchElementException("Empty");
Node<T> main_ptr = start;
Node<T> ref_ptr = start;
int count = 0;
while (count < n) {
if (ref_ptr == null) {
System.out.println(n + " is greater than the no of nodes in the list");
return;
}
ref_ptr = ref_ptr.next;
count++;
}
while (ref_ptr != null) {
main_ptr = main_ptr.next;
ref_ptr = ref_ptr.next;
}
System.out.println("Node no " + n + " from the last is " + main_ptr.data);
}
public void display() {
if (empty())
throw new NoSuchElementException("Empty");
display(start);
}
private void display(Node<T> link) {
if (link != null) {
System.out.print(link.data + " ");
display(link.next);
}
}
public boolean empty() {
return start == null;
}
}
public class LinkedListTest {
public static void main(String[] args) {
LinkedList<Integer> linkedList = new LinkedList<Integer>();
boolean yes = true;
Scanner scanner = new Scanner(System.in);
do {
System.out.println("\n1. Insert At Start");
System.out.println("2. Insert At End");
System.out.println("3. Insert at Position");
System.out.println("4. Delete");
System.out.println("5. Display");
System.out.println("6. Empty status");
System.out.println("7. Get Size");
System.out.println("8. Get Index of the Item");
System.out.println("9. Replace data at given position");
System.out.println("10. Replace data at given position recusively");
System.out.println("11. Get Middle Element");
System.out.println("12. Get Occurence");
System.out.println("13. Reverse Recusively");
System.out.println("14. Reverse");
System.out.println("15. Swap the nodes");
System.out.println("16. Nth Node from last");
System.out.println("\nEnter your choice");
int choice = scanner.nextInt();
switch (choice) {
case 1:
try {
System.out.println("Enter the item");
linkedList.insertAtStart(scanner.nextInt());
} catch (Exception e) {
System.out.println(e.getMessage());
}
break;
case 2:
try {
System.out.println("Enter the item");
linkedList.insertAtEnd(scanner.nextInt());
} catch (Exception e) {
System.out.println(e.getMessage());
}
break;
case 3:
try {
System.out.println("Enter the position");
int position = scanner.nextInt();
if (position < 1 || position > linkedList.size()) {
System.out.println("Invalid Position");
break;
}
System.out.println("Enter the Item");
linkedList.insertAtPosition(position, scanner.nextInt());
} catch (Exception e) {
System.out.println(e.getMessage());
}
break;
case 4:
try {
System.out.println("Enter the position");
int position = scanner.nextInt();
if (position < 1 || position > linkedList.size()) {
System.out.println("Invalid Position");
break;
}
linkedList.delete(position);
} catch (Exception e) {
System.out.println(e.getMessage());
}
break;
case 5:
try {
linkedList.display();
} catch (Exception e) {
System.out.println(e.getMessage());
}
break;
case 6:
System.out.println(linkedList.empty());
break;
case 7:
try {
System.out.println(linkedList.size());
} catch (Exception e) {
System.out.println(e.getMessage());
}
break;
case 8:
try {
System.out.println(linkedList.index(scanner.nextInt()));
} catch (Exception e) {
System.out.println(e.getMessage());
}
break;
case 9:
try {
System.out.println("Enter the position");
int position = scanner.nextInt();
if (position < 1 || position > linkedList.size()) {
System.out.println("Invalid Position");
break;
}
linkedList.replace(position, scanner.nextInt());
} catch (Exception e) {
System.out.println(e.getMessage());
}
break;
case 10:
try {
System.out.println("Enter the position");
int position = scanner.nextInt();
if (position < 1 || position > linkedList.size()) {
System.out.println("Invalid Position");
break;
}
System.out.println("Enter the item");
linkedList.replaceRecursively(position, scanner.nextInt());
} catch (Exception e) {
System.out.println(e.getMessage());
}
break;
case 11:
try {
System.out.println(linkedList.middle());
} catch (Exception e) {
System.out.println(e.getMessage());
}
break;
case 12:
try {
System.out.println("Enter the item");
System.out.println(linkedList.occurence(scanner.nextInt()));
} catch (Exception e) {
System.out.println(e.getMessage());
}
break;
case 13:
try {
linkedList.reverseRecusively();
} catch (Exception e) {
System.out.println(e.getMessage());
}
break;
case 14:
try {
linkedList.reverse();
} catch (Exception e) {
System.out.println(e.getMessage());
}
break;
case 15:
try {
System.out.println("Enter the nodes");
linkedList.swapNode(scanner.nextInt(), scanner.nextInt());
} catch (Exception e) {
System.out.println(e.getMessage());
}
break;
case 16:
try {
System.out.println("Enter which node do you want from last");
linkedList.printNthNodeFromLast(scanner.nextInt());
} catch (Exception e) {
System.out.println(e.getMessage());
}
break;
default:
System.out.println("Invalid Choice");
break;
}
} while (yes);
scanner.close();
}
}

Consider another possible implementation of a working non-recursive Linked List with generic T placeholder. It works out of the box and the code is a more simple one:
import java.util.Iterator;
import java.util.NoSuchElementException;
public class LinkedList<T> implements Iterable<T> {
private Node first;
private Node last;
private int N;
public LinkedList() {
first = null;
last = null;
N = 0;
}
public void add(T item) {
if (item == null) { throw new NullPointerException("Null object!"); }
if (!isEmpty()) {
Node prev = last;
last = new Node(item, null);
prev.next = last;
}
else {
last = new Node(item, null);
first = last;
}
N++;
}
public boolean remove(T item) {
if (isEmpty()) { throw new IllegalStateException("Empty list!"); }
boolean result = false;
Node prev = first;
Node curr = first;
while (curr.next != null || curr == last) {
if (curr.data.equals(item)) {
// remove the last remaining element
if (N == 1) { first = null; last = null; }
// remove first element
else if (curr.equals(first)) { first = first.next; }
// remove last element
else if (curr.equals(last)) { last = prev; last.next = null; }
// remove element
else { prev.next = curr.next; }
N--;
result = true;
break;
}
prev = curr;
curr = prev.next;
}
return result;
}
public int size() {
return N;
}
public boolean isEmpty() {
return N == 0;
}
private class Node {
private T data;
private Node next;
public Node(T data, Node next) {
this.data = data;
this.next = next;
}
}
public Iterator<T> iterator() { return new LinkedListIterator(); }
private class LinkedListIterator implements Iterator<T> {
private Node current = first;
public T next() {
if (!hasNext()) { throw new NoSuchElementException(); }
T item = current.data;
current = current.next;
return item;
}
public boolean hasNext() { return current != null; }
public void remove() { throw new UnsupportedOperationException(); }
}
#Override public String toString() {
StringBuilder s = new StringBuilder();
for (T item : this)
s.append(item + " ");
return s.toString();
}
public static void main(String[] args) {
LinkedList<String> list = new LinkedList<>();
while(!StdIn.isEmpty()) {
String input = StdIn.readString();
if (input.equals("print")) { StdOut.println(list.toString()); continue; }
if (input.charAt(0) == ('+')) { list.add(input.substring(1)); continue; }
if (input.charAt(0) == ('-')) { list.remove(input.substring(1)); continue; }
break;
}
}
}
For more LinkedList examples, your can check out the article.

Related

Remove Method for a Single and Double Linked List (Java)

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.

How to sorting list interface

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>

Singly Linked List: Removing

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;
}
}

Binary Search Tree - Java Implementation

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();
}
}

avl tree rotation

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.

Categories