Right Rotation Binary Search Tree Java - java

I am brushing up on some simple data structures and I am having trouble making the rotations in my BST work properly.
public class BinarySearchTree {
private static class Node {
Node parent; //null for root node
Node left;
Node right;
int data;
//constructor for node
Node(int newData) {
left = null;
right = null;
parent = null;
data = newData;
}
}
private Node root; //root null in empty
//search methods
public boolean search(int data) {
return search(root,data); //true if exists
}
private boolean search(Node n, int data) {
if(n == null)
return false; //node doesn't exist
if(data == n.data) //found
return true;
else if(data < n.data) //data on left if exists
return search(n.left, data);
else //data on right if it exists
return search(n.right,data);
}
public Node findNode(int data) {
return findNode(root,data);
}
private Node findNode(Node n, int data) {
if(n == null)
return n; //nothing exists here
else if (data < n.data) //data should be on left if it exists
return findNode(n.left,data);
else if(data > n.data) //data should be on right if it exists
return findNode(n.right,data);
else
return n; //found it
}
//recursive insertion
public void insertNode(int data) {
root = insertNode(root,null,data);
}
private Node insertNode(Node n, Node parentNode, int data) {
if(n == null) {
n = new Node(data); //if node doesn't exist add it here
n.parent = parentNode;
}
else {
if(data <= n.data) {
n.left = insertNode(n.left,n,data);
} else {
n.right = insertNode(n.right,n,data);
}
}
return n; //return self at end (will go back to root)
}
//rotations
public void rotateLeft(Node n) {
Node y = n.right;
n.right = y.left; //y's left subtree into n's right subtree
if(y.left != null)
y.left.parent = n;
y.parent = n.parent;
//link n's parent to y
if(n.parent == null) //check to see if we are at root
root = y;
else if(n == n.parent.left) //n on left of parent
n.parent.left = y;
else //n on right of parent
n.parent.right = y;
y.left = n;
n.parent = y; //n on y's left
}
public void rotateRight(Node n) {
Node y = n.left;
n.left = y.right;
if(y.right != null)
y.right.parent = n;
y.parent = n.parent;
if(n.parent == null)
root = y;
else if(n == n.parent.right)
n.parent.right = y;
else
n.parent.left = y;
y.right = n;
n.parent = y;
}
//Printing
public void printPreorder() {
printPreorder(root);
}
private void printPreorder(Node n) {
if(n == null) //nothing here
return;
System.out.print(n.data + " "); //print node data here
printPreorder(n.left);
printPreorder(n.right);
}
public void printInorder() {
printInorder(root);
}
private void printInorder(Node n) {
if(n == null) //nothing here
return;
printInorder(n.left);
System.out.print(n.data + " "); //print data here (in order)
printInorder(n.right);
}
public void printPostorder() {
printPostorder(root);
}
private void printPostorder(Node n) {
if(n == null)
return; //nothing here
printPostorder(n.left);
printPostorder(n.right);
//node is here so print data
System.out.print(n.data + " ");
}
}
quick messy main
public class MainBST {
public static void main(String args[]) {
BinarySearchTree BST = new BinarySearchTree();
//test run
BST.insertNode(8);
BST.insertNode(7);
BST.insertNode(5);
BST.insertNode(6);
BST.insertNode(3);
BST.insertNode(4);
System.out.print("Before rotation: \nPre-order: ");
BST.printPreorder();
System.out.print("\nIn-order: ");
BST.printInorder();
System.out.print("\nPost-order: ");
BST.printPostorder();
if(BST.search(5))
BST.rotateRight(BST.findNode(5));
System.out.print("\n\nAfter rotation: \nPre-order: ");
BST.printPreorder();
System.out.print("\nIn-order: ");
BST.printInorder();
System.out.print("\nPost-order: ");
BST.printPostorder();
}
}
The output:
Before rotation:
Pre-order: 8 7 5 3 4 6
In-order: 3 4 5 6 7 8
Post-order: 4 3 6 5 7 8
After rotation:
Pre-order: 8 7 3 5 4 6
In-order: 3 4 5 6 7 8
Post-order: 4 6 5 3 7 8
However this is the expected output after rotation (I have the right output for the tree before rotation):
Pre-order: 8 5 3 4 7 6
In-order: 3 4 5 6 7 8
Post-order: 4 3 6 7 5 8
It is clear there is some problem. Maybe it has to do with my wonky findNode() or the node structure? Or possibly even the rotation method has a problem. Can anyone help me out?

Related

How to insert data into a binary tree in level order?

As the title suggests, I am currently trying to construct a binary tree wherein user inputs are inserted in in-level order. Almost all of the tutorials and implementations in Java that I've read uses a sorted method of insertion.
I've tried gfg's method, but it uses queues, which resulted me being graded 0.
gfg method:
void addData(int data) {
Node newNode = new Node(data);
if (root == null) {
root = newNode;
} else {
Queue<Node> queue = new LinkedList<>();
queue.add(root);
while (true) {
Node node = queue.remove();
if (node.left != null && node.right != null) {
queue.add(node.left);
queue.add(node.right);
}
else {
if (node.left == null) {
node.left = newNode;
queue.add(node.left);
} else {
node.right = newNode;
queue.add(node.right);
}
break;
}
}
}
}
Input: 1 2 3 4 5 6 7
Output (In-order): 4 2 5 1 6 3 7 (Correct, but as mentioned it uses queues)
The insertion that I understand w/o queues (but this one sorts user input):
private Node insertNode(Node current, int data) {
if (current == null) {
return new Node(data);
}
if (data < current.data) {
current.left = insertNode(current.left, data);
}
else if (data > current.data) {
current.right = insertNode(current.right, data);
}
else {
return current;
}
return current;
}
public void addNode(int data) {
root = insertNode(root, data);
}
Input: 1 2 3 4 5 6 7
Output (In-Order): 1 2 3 4 5 6 7
To note, yes, I've also tried to implement gfg's method to what I understand. But I personally cannot make it make sense? I'm really stuck.
Edit:
The whole code:
import java.util.Scanner;
public class BinaryTree {
static class Node {
int data;
Node left;
Node right;
Node(int data) {
this.data = data;
right = left = null;
}
}
public static class treeBinary {
Node root;
treeBinary() {
root = null;
}
private Node insertNode(Node current, int data) {
if (current == null) {
return new Node(data);
}
if (data < current.data) {
current.left = insertNode(current.left, data);
}
else if (data > current.data) {
current.right = insertNode(current.right, data);
}
else {
return current;
}
return current;
}
public void addNode(int data) {
root = insertNode(root, data);
}
public void inorderPrint(Node node) {
if (node != null) {
inorderPrint(node.left);
System.out.print(" " + node.data);
inorderPrint(node.right);
}
}
void inorderPrint() {
inorderPrint(root);
}
public void preorderPrint(Node node) {
if (node != null) {
System.out.print(" " + node.data);
preorderPrint(node.left);
preorderPrint(node.right);
}
}
void preorderPrint() {
preorderPrint(root);
}
public void postorderPrint(Node node) {
if (node != null) {
postorderPrint(node.left);
postorderPrint(node.right);
System.out.print(" " + node.data);
}
}
void postorderPrint() {
postorderPrint(root);
}
}
public static void main(String[] args) {
Scanner inputUser = new Scanner(System.in);
treeBinary userBT = new treeBinary();
boolean userChoice = false;
int count = 0;
mainMenu:
do {
System.out.println("\n\n\n1 - Add Data");
System.out.println("2 - Print (In-Order)");
System.out.println("3 - Print (Pre-Order");
System.out.println("4 - Print (Post-Order)");
System.out.println("5 - Exit");
System.out.print("Enter your choice: ");
switch (inputUser.nextInt()) {
case 1:
System.out.print("How many will you input? ");
int x = inputUser.nextInt();
for (int i = 0; i < x; i++) {
System.out.print("Input Data " + (count+1) + ": ");
userBT.addNode(inputUser.nextInt());
count++;
}
break;
case 2:
System.out.println("The Tree in In-Order: ");
userBT.inorderPrint();
break;
case 3:
System.out.println("The Tree in Pre-Order: ");
userBT.preorderPrint();
break;
case 4:
System.out.println("The Tree in Post-Order: ");
userBT.postorderPrint();
break;
case 5:
break mainMenu;
default:
System.out.println("Invalid Input!");
}
}
while (!userChoice);
}
}
After days and hours of trying and reading. I applied the idea of balancing the tree from the user's inputs instead of inserting in comparison with the previous input data. Personally, I don't know if this is what the professor is looking for, but I'll try and try. Thanks #trincot
Here is what I've came up with, just a mishmash of everything that I've read and watched, nothing original:
public static class treeBinary {
boolean checkBal(int countSide) {
countSide = countSide + 1;
while (countSide % 2 == 0) {
countSide = countSide / 2;
}
if (countSide == 1) {
return true;
}
else {
return false;
}
}
Node insertData(Node root, int data) {
if (root == null) {
Node newNode = new Node(data);
return newNode;
}
if (root.rightSide == root.leftSide) {
root.left = insertData(root.left, data);
root.leftSide++;
}
else if (root.rightSide < root.leftSide) {
if (checkBal(root.leftSide)) {
root.right = insertData(root.right, data);
root.rightSide++;
}
else {
root.left = insertData(root.left, data);
root.leftSide++;
}
}
return root;
}
void inorderPrint(Node node) {
if (node != null) {
inorderPrint(node.left);
System.out.print(node.data + " ");
inorderPrint(node.right);
}
}
}
I'll try to refine even more to the extent of my knowledge as a learning student.

how to create binary search tree 2d model from these codes?

hi im new to codings and i have to print my binary search tree in a 2d model but this codes only print the orders of number in order(left-root-right) such as when i insert 10, 9, 11, 8, it will print inorder (left root right) = 8,9,10,11. what method or codes should i add to create a 2d tree here. sorry idk how to properly put the codes here just look at it like it is only a one code only.
class binarySearchTree {
class Node {
int key;
Node left, right;
int data;
public Node(int data){
key = data;
left = right = null;
}
}
// BST root node
Node root;
// Constructor for BST =>initial empty tree
binarySearchTree(){
root = null;
}
//delete a node from BST
void deleteKey(int key) {
root = delete_Recursive(root, key);
}
//recursive delete function
Node delete_Recursive(Node root, int key) {
//tree is empty
if (root == null) return root;
//traverse the tree
if (key < root.key) //traverse left subtree
root.left = delete_Recursive(root.left, key);
else if (key > root.key) //traverse right subtree
root.right = delete_Recursive(root.right, key);
else {
// node contains only one child
if (root.left == null)
return root.right;
else if (root.right == null)
return root.left;
// node has two children;
//get inorder successor (min value in the right subtree)
root.key = minValue(root.right);
// Delete the inorder successor
root.right = delete_Recursive(root.right, root.key);
}
return root;
}
int minValue(Node root) {
//initially minval = root
int minval = root.key;
//find minval
while (root.left != null) {
minval = root.left.key;
root = root.left;
}
return minval;
}
// insert a node in BST
void insert(int key) {
root = insert_Recursive(root, key);
}
//recursive insert function
Node insert_Recursive(Node root, int key) {
//tree is empty
if (root == null) {
root = new Node(key);
return root;
}
//traverse the tree
if (key < root.key) //insert in the left subtree
root.left = insert_Recursive(root.left, key);
else if (key > root.key) //insert in the right subtree
root.right = insert_Recursive(root.right, key);
// return pointer
return root;
}
void inorder() {
inorder_Recursive(root);
}
// recursively traverse the BST
void inorder_Recursive(Node root) {
if (root != null) {
inorder_Recursive(root.left);
System.out.print(root.key + " x ");
inorder_Recursive(root.right);
}
}
//PostOrder Traversal - Left:Right:rootNode (LRn)
void postOrder(Node node) {
if (node == null)
return;
// first traverse left subtree recursively
postOrder(node.left);
// then traverse right subtree recursively
postOrder(node.right);
// now process root node
System.out.print(node.key + " ");
}
// InOrder Traversal - Left:rootNode:Right (LnR)
void inOrder(Node node) {
if (node == null)
return;
//first traverse left subtree recursively
inOrder(node.left);
//then go for root node
System.out.print(node.key + " ");
//next traverse right subtree recursively
inOrder(node.right);
}
//PreOrder Traversal - rootNode:Left:Right (nLR)
void preOrder(Node node) {
if (node == null)
return;
//first print root node first
System.out.print(node.key + " ");
// then traverse left subtree recursively
preOrder(node.left);
// next traverse right subtree recursively
preOrder(node.right);
}
// Wrappers for recursive functions
void postOrder_traversal() {
postOrder(root); }
void inOrder_traversal() {
inOrder(root); }
void preOrder_traversal() {
preOrder(root); }
}
here i found this codes in stackoverflow, i want te output like this, i can use this but i dont know how can i make this as user input for the data and make it insert the integer into a tree not this manually inserted of the integer. thankyou very much to whoever put effort to understand my question and my situation as newbie.
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
public class BTreePrinterTest {
private static Node<Integer> test2() {
Node<Integer> root = new Node<Integer>(2);
Node<Integer> n11 = new Node<Integer>(3);
Node<Integer> n12 = new Node<Integer>(5);
Node<Integer> n21 = new Node<Integer>(2);
Node<Integer> n22 = new Node<Integer>(6);
Node<Integer> n23 = new Node<Integer>(9);
Node<Integer> n31 = new Node<Integer>(5);
root.left = n11;
root.right = n12;
n11.left = n21;
n11.right = n22;
n12.left = n23;
n12.right = n31;
return root;
}
public static void main(String[] args) {
BTreePrinter.printNode(test2());
}
}
class Node<T extends Comparable<?>> {
Node<T> left, right;
T data;
public Node(T data) {
this.data = data;
}
}
class BTreePrinter {
public static <T extends Comparable<?>> void printNode(Node<T> root) {
int maxLevel = BTreePrinter.maxLevel(root);
printNodeInternal(Collections.singletonList(root), 1, maxLevel);
}
private static <T extends Comparable<?>> void printNodeInternal(List<Node<T>> nodes, int level, int maxLevel) {
if (nodes.isEmpty() || BTreePrinter.isAllElementsNull(nodes))
return;
int floor = maxLevel - level;
int endgeLines = (int) Math.pow(2, (Math.max(floor - 1, 0)));
int firstSpaces = (int) Math.pow(2, (floor)) - 1;
int betweenSpaces = (int) Math.pow(2, (floor + 1)) - 1;
BTreePrinter.printWhitespaces(firstSpaces);
List<Node<T>> newNodes = new ArrayList<Node<T>>();
for (Node<T> node : nodes) {
if (node != null) {
System.out.print(node.data);
newNodes.add(node.left);
newNodes.add(node.right);
} else {
newNodes.add(null);
newNodes.add(null);
System.out.print(" ");
}
BTreePrinter.printWhitespaces(betweenSpaces);
}
System.out.println("");
for (int i = 1; i <= endgeLines; i++) {
for (int j = 0; j < nodes.size(); j++) {
BTreePrinter.printWhitespaces(firstSpaces - i);
if (nodes.get(j) == null) {
BTreePrinter.printWhitespaces(endgeLines + endgeLines + i + 1);
continue;
}
if (nodes.get(j).left != null)
System.out.print("/");
else
BTreePrinter.printWhitespaces(1);
BTreePrinter.printWhitespaces(i + i - 1);
if (nodes.get(j).right != null)
System.out.print("\\");
else
BTreePrinter.printWhitespaces(1);
BTreePrinter.printWhitespaces(endgeLines + endgeLines - i);
}
System.out.println("");
}
printNodeInternal(newNodes, level + 1, maxLevel);
}
private static void printWhitespaces(int count) {
for (int i = 0; i < count; i++)
System.out.print(" ");
}
private static <T extends Comparable<?>> int maxLevel(Node<T> node) {
if (node == null)
return 0;
return Math.max(BTreePrinter.maxLevel(node.left), BTreePrinter.maxLevel(node.right)) + 1;
}
private static <T> boolean isAllElementsNull(List<T> list) {
for (Object object : list) {
if (object != null)
return false;
}
return true;
}
}
btw im learning this by my own, i tried merging the two codes but it gives me error i cant fix it.
I should have not made the whole exercise for you, so please try to understand the code. Tell me if something is not clear for you.
public static void main(String[] args) throws IOException {
System.out.println("Write your input");
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
String lines = br.readLine();
binarySearchTree b = new binarySearchTree();
b.input(lines);
b.print();
}
These functions go to binarySearchTree.
protected void printRecursive(Node node, int depth) {
System.out.println("");
for(int i = 0; i<depth; i++) {
System.out.print(" ");
}
System.out.print(node.key);
if(node.left != null) {
printRecursive(node.left, depth + 1);
}
if(node.right != null) {
printRecursive(node.right, depth + 1);
}
}
public void input(String s) throws IOException {
String[] strs = s.trim().split("\\s+");
for (int i = 0; i < strs.length; i++) {
insert(Integer.parseInt(strs[i]));
}
}
Also i used this answer in my code.

from a stack a number of options as 1,2,3 is given by user and we need to perform operations as specified

Question is:
You have an empty sequence, and you will be given N queries. Each query is one of these three types:
Push the element x into the stack.
Delete the element present at the top of the stack.
Print the maximum element in the stack.
I am not able to identify error in my code could anyone please help..
import java.io.*;
import java.util.*;
class Node {
int data;
Node next;
public Node(int data) {
this.data = data;
this.next = null;
}
}
public class Solution {
public Node head;
public void push(int data) //insert at begin
{
Node newNode = new Node(data);
newNode.next = head;
head = newNode;
}
public void pop() //deletion at begin
{
if (head == null) {
System.out.print("stack underFlow");
return;
}
head = head.next;
}
public int maxele(Node head) {
Node max = head;
Node temp = head;
while (temp != null) {
if (max.data > temp.data)
max = temp;
temp = temp.next;
}
return max.data;
}
public void display() {
Node temp = head;
while (temp != null) {
System.out.print(temp.data + "");
temp = temp.next;
}
}
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
Solution obj = new Solution();
int maximumElement;
int N, i = 0;
int test;
N = sc.nextInt();
while (i < N) {
test = sc.nextInt();
if (test == 1) {
obj.push(sc.nextInt());
} else if (test == 2) {
obj.pop();
} else if (test == 3) {
maximumElement = obj.maxele(obj.head);
System.out.println(maximumElement);
System.out.println();
}
i++;
}
}
}
//input is:
10 //here 10 is number of test cases
1 97 //here 1 means push
2 //here 2 means pop
1 20
2
1 26
1 20
2
3 //3 means Print the maximum element in the stack
1 91
3
//my code gives output as:
26
26
You did not explain exactly what the problem was, nor what you expected. However, I'm guessing that your problem is that the "getMaximum" routine did not return the largest value in the stack.
Assuming that is the problem, the following version of the code should do what you expect.
Apart from changing the class name, putting it in a package and enabling function 4 (display the stack) and some minor formatting the program is the same - except for the test in the "getMaximum" routine. I've added some comments there explaining how your original line should be read and how my variant of it should be read.
Of course you could have also used if (max.data < temp.data) if you prefer to read it that way. I personally do not like it that way (I like to compare my data to my tracked value), but 50% of the population do like it that way, so who am I to argue!
package stackexercise;
import java.util.*;
class Node {
int data;
Node next;
public Node(int data) {
this.data = data;
this.next = null;
}
}
public class StackExercise {
public Node head;
public void push(int data) //insert at begin
{
Node newNode = new Node(data);
newNode.next = head;
head = newNode;
}
public Node pop() //deletion at begin
{
if (head == null) {
System.out.print("stack underFlow");
return null;
}
Node x = head;
head = head.next;
return x;
}
public int maxele(Node head) {
Node max = head;
Node temp = head;
while (temp != null) {
// My guess is that this is what is wrong.
// This calculates minimum value (not the max).
// Read it as:
// If the number we are tracking is bigger than the
// current data element(i.e. current element is smaller),
// capture this (smaller) data element as the new value.
//if (max.data > temp.data)
// Whereas this can be read as:
// If this data element is bigger than the value we are tracking
// capture this (bigger) data element as the new value.
if (temp.data > max.data)
max = temp;
temp = temp.next;
}
return max.data;
}
public void display() {
System.out.println("Stack contents:");
Node temp = head;
while (temp != null) {
System.out.print(temp.data + " ");
temp = temp.next;
}
System.out.println();
}
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
StackExercise obj = new StackExercise();
int maximumElement;
int N, i = 0;
int test;
N = sc.nextInt();
while (i < N) {
test = sc.nextInt();
if (test == 1) {
obj.push(sc.nextInt());
} else if (test == 2) {
Node x = obj.pop();
if (x != null) {
System.out.printf("popped: %d\n", x.data);
} else {
System.out.println("Stack empty");
}
} else if (test == 3) {
maximumElement = obj.maxele(obj.head);
System.out.println(maximumElement);
System.out.println();
} else if (test == 4) {
obj.display();
}
i++;
}
}
}
And here is a run (with two extra steps to display the current stack):
12
1 97
2
1 20
2
1 26
1 20
2
4
3
1 91
4
3
popped: 97
popped: 20
popped: 20
Stack contents:
26
26
Stack contents:
91 26
91
BTW, did you know that Java already has a Stack class? It does all of the basic things you need a stack to do (push, pop etc). Believe it or not, the class is called Stack. Here is the java version 8 javadoc for Stack class.

Adding Number Represented by Linked List

I'm stuck on this problem:
You have two numbers represented by a linked list, where each node contains a single digit. The digits are stored in reverse order, such that the 1’s digit is at the head of the list. Write a function that adds the two numbers and returns the sum as a linked list.
EXAMPLE
Input: (3 -> 1 -> 5), (5 -> 9 -> 2)
Output: 8 -> 0 -> 8
The problem is that my result is 8 8 while the result should be 8 0 8.
I printed out the sum and it is 8 10 8 so it should work.
Any ideas?
Here is my code:
public Node addNumbers(Node number1, Node number2) {
if(number1 == null && number2 == null)
return null;
Node sumOf = null;
int sum = 0;
int carry = 0;
while(number1 != null && number2 != null) {
sum = number1.data + number2.data + carry;
System.out.println(sum);
// update carry for next operation
if(sum > 9)
carry = 1;
else
carry = 0;
if(sum > 9) {
if(sumOf == null) {
sumOf = new Node(sum % 10);
} else {
sumOf.next = new Node(sum % 10);
}
} else {
if(sumOf == null) {
sumOf = new Node(sum);
} else {
sumOf.next = new Node(sum);
}
}
number1 = number1.next;
number2 = number2.next;
}
return sumOf;
}
public void toString(Node node) {
System.out.println();
while (node != null) {
System.out.print(node.data + " ");
node = node.next;
}
}
public static void main(String[] args) {
AddTwoNumbers add = new AddTwoNumbers();
number1 = new Node(3);
number1.next = new Node(1);
number1.next.next = new Node(5);
number2 = new Node(5);
number2.next = new Node(9);
number2.next.next = new Node(2);
System.out.println("numbers: ");
add.toString(number1);
add.toString(number2);
System.out.println();
System.out.println("after adding: ");
add.toString(add.addNumbers(number1, number2));
}
}
You only ever set sumOf (if it is null) and sumOf.next (if sumOf is not null). Your resulting list therefore never has more than two elements. You need to track the current tail of your list and append there, instead of always appending to sumOf.
Additionally, you need to handle the cases where one input number has more digits than the other, and where you have non-zero carry after exhausting all the input digits. You do not presently handle either.
Here is the solution, do note that i carry forward when the sum of two integers is greater than 9 else i continue with the sum of next integers from both the list.
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 Node(final Object data, final Node next) {
this.data = data;
this.next = next;
}
#Override
public String toString() { return "Node:[Data=" + data + "]"; }
}
class SinglyLinkedList {
Node start;
public SinglyLinkedList() { start = null; }
public void addFront(final Object data) {
// create a reference to the start node with new data
Node node = new Node(data, start);
// assign our start to a new node
start = node;
}
public void addRear(final Object data) {
Node node = new Node(data, null);
Node current = start;
if (current != null) {
while (current.getNext() != null) {
current = current.getNext();
}
current.setNext(node);
} else {
addFront(data);
}
}
public void deleteNode(final Object data) {
Node previous = start;
if (previous == null) {
return;
}
Node current = previous.getNext();
if (previous != null && previous.getData().equals(data)) {
start = previous.getNext();
previous = current;
current = previous.getNext();
return;
}
while (current != null) {
if (current.getData().equals(data)) {
previous.setNext(current.getNext());
current = previous.getNext();
} else {
previous = previous.getNext();
current = previous.getNext();
}
}
}
public Object getFront() {
if (start != null) {
return start.getData();
} else {
return null;
}
}
public void print() {
Node current = start;
if (current == null) {
System.out.println("SingleLinkedList is Empty");
}
while (current != null) {
System.out.print(current);
current = current.getNext();
if (current != null) {
System.out.print(", ");
}
}
}
public int size() {
int size = 0;
Node current = start;
while (current != null) {
current = current.getNext();
size++;
}
return size;
}
public Node getStart() {
return this.start;
}
public Node getRear() {
Node current = start;
Node previous = current;
while (current != null) {
previous = current;
current = current.getNext();
}
return previous;
}
}
public class AddNumbersInSinglyLinkedList {
public static void main(String[] args) {
SinglyLinkedList listOne = new SinglyLinkedList();
SinglyLinkedList listTwo = new SinglyLinkedList();
listOne.addFront(5);
listOne.addFront(1);
listOne.addFront(3);
listOne.print();
System.out.println();
listTwo.addFront(2);
listTwo.addFront(9);
listTwo.addFront(5);
listTwo.print();
SinglyLinkedList listThree = add(listOne, listTwo);
System.out.println();
listThree.print();
}
private static SinglyLinkedList add(SinglyLinkedList listOne, SinglyLinkedList listTwo) {
SinglyLinkedList result = new SinglyLinkedList();
Node startOne = listOne.getStart();
Node startTwo = listTwo.getStart();
int carry = 0;
while (startOne != null || startTwo != null) {
int one = 0;
int two = 0;
if (startOne != null) {
one = (Integer) startOne.getData();
startOne = startOne.getNext();
}
if (startTwo != null) {
two = (Integer) startTwo.getData();
startTwo = startTwo.getNext();
}
int sum = carry + one + two;
carry = 0;
if (sum > 9) {
carry = sum / 10;
result.addRear(sum % 10);
} else {
result.addRear(sum);
}
}
return result;
}
}
Sample Run
Node:[Data=3], Node:[Data=1], Node:[Data=5]
Node:[Data=5], Node:[Data=9], Node:[Data=2]
Node:[Data=8], Node:[Data=0], Node:[Data=8]
**#In Python:-**
class Node():
def __init__(self,value):
self.value=value
self.nextnode=None
class LinkedList():
def __init__(self):
self.head=None
def add_element(self,value):
node=Node(value)
if self.head is None:
self.head =node
return
crnt_node=self.head
while crnt_node.nextnode is not None:
crnt_node=crnt_node.nextnode
crnt_node.nextnode=node
def reverse_llist(self):
crnt_node=self.head
if crnt_node == None:
print('Empty Linkned List')
return
old_node = None
while crnt_node:
temp_node = crnt_node.nextnode
crnt_node.nextnode = old_node
old_node = crnt_node
crnt_node = temp_node
self.head = old_node
def converted_llist(self):
crnt_node=self.head
carry_value=0
while True:
#print(crnt_node.value)
if (crnt_node.value+1)%10==0:
carry_value=1
crnt_node.value=0
print(crnt_node.value,end='->')
else:
print(crnt_node.value+carry_value,end='->')
if crnt_node.nextnode is None:
break
crnt_node=crnt_node.nextnode
print('None')
def print_llist(self):
crnt_node=self.head
while True:
print(crnt_node.value,end='->')
if crnt_node.nextnode is None:
break
crnt_node=crnt_node.nextnode
print('None')
list_convert=LinkedList()
list_convert.add_element(1)
list_convert.print_llist()
list_convert.add_element(9)
list_convert.print_llist()
list_convert.add_element(9)
list_convert.print_llist()
list_convert.add_element(9)
list_convert.print_llist()
list_convert.reverse_llist()
list_convert.print_llist()
list_convert.converted_llist()

Binary Heap Implemented via a Binary Tree Structure

For an assignment, we were instructed to create a priority queue implemented via a binary heap, without using any built-in classes, and I have done so successfully by using an array to store the queued objects. However, I'm interested in learning how to implement another queue by using an actual tree structure, but in doing so I've run across a bit of a problem.
How would I keep track of the nodes on which I would perform insertion and deletion? I have tried using a linked list, which appends each node as it is inserted - new children are added starting from the first list node, and deleted from the opposite end. However, this falls apart when elements are rearranged in the tree, as children are added at the wrong position.
Edit: Perhaps I should clarify - I'm not sure how I would be able to find the last occupied and first unoccupied leaves. For example, I would always be able to tell the last inserted leaf, but if I were to delete it, how would I know which leaf to delete when I next remove the item? The same goes for inserting - how would I know which leaf to jump to next after the current leaf has both children accounted for?
A tree implementation of a binary heap uses a complete tree [or almost full tree: every level is full, except the deepest one].
You always 'know' which is the last occupied leaf - where you delete from [and modifying it is O(logn) after it changed so it is not a problem], and you always 'know' which is the first non-occupied leaf, in which you add elements to [and again, modifying it is also O(logn) after it changed].
The algorithm idea is simple:
insert: insert element to the first non-occupied leaf, and use heapify [sift up] to get this element to its correct place in the heap.
delete_min: replace the first element with the last occupied leaf, and remove the last occupied leaf. then, heapify [sift down] the heap.
EDIT: note that delete() can be done to any element, and not only the head, however - finding the element you want to replace with the last leaf will be O(n), which will make this op expensive. for this reason, the delete() method [besides the head], is usually not a part of the heap data structure.
I really wanted to do this for almost a decade.Finally sat down today and wrote it.Anyone who wants it can use it.I got inspired by Quora founder to relearn Heap.Apparently he was asked how would you find K near points in a set of n points in his Google phone screen.Apparently his answer was to use a Max Heap and to store K values and remove the maximum element after the size of the heap exceeds K.The approach is pretty simple and the worst case is nlog K which is better than n^2 in most sorting cases.Here is the code.
import java.util.ArrayList;
import java.util.List;
/**
* #author Harish R
*/
public class HeapPractise<T extends Comparable<T>> {
private List<T> heapList;
public List<T> getHeapList() {
return heapList;
}
public void setHeapList(List<T> heapList) {
this.heapList = heapList;
}
private int heapSize;
public HeapPractise() {
this.heapList = new ArrayList<>();
this.heapSize = heapList.size();
}
public void insert(T item) {
if (heapList.size() == 0) {
heapList.add(item);
} else {
siftUp(item);
}
}
public void siftUp(T item) {
heapList.add(item);
heapSize = heapList.size();
int currentIndex = heapSize - 1;
while (currentIndex > 0) {
int parentIndex = (int) Math.floor((currentIndex - 1) / 2);
T parentItem = heapList.get(parentIndex);
if (parentItem != null) {
if (item.compareTo(parentItem) > 0) {
heapList.set(parentIndex, item);
heapList.set(currentIndex, parentItem);
currentIndex = parentIndex;
continue;
}
}
break;
}
}
public T delete() {
if (heapList.size() == 0) {
return null;
}
if (heapList.size() == 1) {
T item = heapList.get(0);
heapList.remove(0);
return item;
}
return siftDown();
}
public T siftDown() {
T item = heapList.get(0);
T lastItem = heapList.get(heapList.size() - 1);
heapList.remove(heapList.size() - 1);
heapList.set(0, lastItem);
heapSize = heapList.size();
int currentIndex = 0;
while (currentIndex < heapSize) {
int leftIndex = (2 * currentIndex) + 1;
int rightIndex = (2 * currentIndex) + 2;
T leftItem = null;
T rightItem = null;
int currentLargestItemIndex = -1;
if (leftIndex <= heapSize - 1) {
leftItem = heapList.get(leftIndex);
}
if (rightIndex <= heapSize - 1) {
rightItem = heapList.get(rightIndex);
}
T currentLargestItem = null;
if (leftItem != null && rightItem != null) {
if (leftItem.compareTo(rightItem) >= 0) {
currentLargestItem = leftItem;
currentLargestItemIndex = leftIndex;
} else {
currentLargestItem = rightItem;
currentLargestItemIndex = rightIndex;
}
} else if (leftItem != null && rightItem == null) {
currentLargestItem = leftItem;
currentLargestItemIndex = leftIndex;
}
if (currentLargestItem != null) {
if (lastItem.compareTo(currentLargestItem) >= 0) {
break;
} else {
heapList.set(currentLargestItemIndex, lastItem);
heapList.set(currentIndex, currentLargestItem);
currentIndex = currentLargestItemIndex;
continue;
}
}
}
return item;
}
public static void main(String[] args) {
HeapPractise<Integer> heap = new HeapPractise<>();
for (int i = 0; i < 32; i++) {
heap.insert(i);
}
System.out.println(heap.getHeapList());
List<Node<Integer>> nodeArray = new ArrayList<>(heap.getHeapList()
.size());
for (int i = 0; i < heap.getHeapList().size(); i++) {
Integer heapElement = heap.getHeapList().get(i);
Node<Integer> node = new Node<Integer>(heapElement);
nodeArray.add(node);
}
for (int i = 0; i < nodeArray.size(); i++) {
int leftNodeIndex = (2 * i) + 1;
int rightNodeIndex = (2 * i) + 2;
Node<Integer> node = nodeArray.get(i);
if (leftNodeIndex <= heap.getHeapList().size() - 1) {
Node<Integer> leftNode = nodeArray.get(leftNodeIndex);
node.left = leftNode;
}
if (rightNodeIndex <= heap.getHeapList().size() - 1) {
Node<Integer> rightNode = nodeArray.get(rightNodeIndex);
node.right = rightNode;
}
}
BTreePrinter.printNode(nodeArray.get(0));
}
}
public class Node<T extends Comparable<?>> {
Node<T> left, right;
T data;
public Node(T data) {
this.data = data;
}
}
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
class BTreePrinter {
public static <T extends Comparable<?>> void printNode(Node<T> root) {
int maxLevel = BTreePrinter.maxLevel(root);
printNodeInternal(Collections.singletonList(root), 1, maxLevel);
}
private static <T extends Comparable<?>> void printNodeInternal(
List<Node<T>> nodes, int level, int maxLevel) {
if (nodes.isEmpty() || BTreePrinter.isAllElementsNull(nodes))
return;
int floor = maxLevel - level;
int endgeLines = (int) Math.pow(2, (Math.max(floor - 1, 0)));
int firstSpaces = (int) Math.pow(2, (floor)) - 1;
int betweenSpaces = (int) Math.pow(2, (floor + 1)) - 1;
BTreePrinter.printWhitespaces(firstSpaces);
List<Node<T>> newNodes = new ArrayList<Node<T>>();
for (Node<T> node : nodes) {
if (node != null) {
String nodeData = String.valueOf(node.data);
if (nodeData != null) {
if (nodeData.length() == 1) {
nodeData = "0" + nodeData;
}
}
System.out.print(nodeData);
newNodes.add(node.left);
newNodes.add(node.right);
} else {
newNodes.add(null);
newNodes.add(null);
System.out.print(" ");
}
BTreePrinter.printWhitespaces(betweenSpaces);
}
System.out.println("");
for (int i = 1; i <= endgeLines; i++) {
for (int j = 0; j < nodes.size(); j++) {
BTreePrinter.printWhitespaces(firstSpaces - i);
if (nodes.get(j) == null) {
BTreePrinter.printWhitespaces(endgeLines + endgeLines + i
+ 1);
continue;
}
if (nodes.get(j).left != null)
System.out.print("//");
else
BTreePrinter.printWhitespaces(1);
BTreePrinter.printWhitespaces(i + i - 1);
if (nodes.get(j).right != null)
System.out.print("\\\\");
else
BTreePrinter.printWhitespaces(1);
BTreePrinter.printWhitespaces(endgeLines + endgeLines - i);
}
System.out.println("");
}
printNodeInternal(newNodes, level + 1, maxLevel);
}
private static void printWhitespaces(int count) {
for (int i = 0; i < 2 * count; i++)
System.out.print(" ");
}
private static <T extends Comparable<?>> int maxLevel(Node<T> node) {
if (node == null)
return 0;
return Math.max(BTreePrinter.maxLevel(node.left),
BTreePrinter.maxLevel(node.right)) + 1;
}
private static <T> boolean isAllElementsNull(List<T> list) {
for (Object object : list) {
if (object != null)
return false;
}
return true;
}
}
Please note that BTreePrinter is a code I took somewhere in Stackoverflow long back and I modified to use with 2 digit numbers.It will be broken if we move to 3 digit numbers and it is only for simple understanding of how the Heap structure looks.A fix for 3 digit numbers is to keep everything as multiple of 3.
Also due credits to Sesh Venugopal for wonderful tutorial on Youtube on Heap data structure
public class PriorityQ<K extends Comparable<K>> {
private class TreeNode<T extends Comparable<T>> {
T val;
TreeNode<T> left, right, parent;
public String toString() {
return this.val.toString();
}
TreeNode(T v) {
this.val = v;
left = null;
right = null;
}
public TreeNode<T> insert(T val, int position) {
TreeNode<T> parent = findNode(position/2);
TreeNode<T> node = new TreeNode<T>(val);
if(position % 2 == 0) {
parent.left = node;
} else {
parent.right = node;
}
node.parent = parent;
heapify(node);
return node;
}
private void heapify(TreeNode<T> node) {
while(node.parent != null && (node.parent.val.compareTo(node.val) < 0)) {
T temp = node.val;
node.val = node.parent.val;
node.parent.val = temp;
node = node.parent;
}
}
private TreeNode<T> findNode(int pos) {
TreeNode<T> node = this;
int reversed = 1;
while(pos > 0) {
reversed <<= 1;
reversed |= (pos&1);
pos >>= 1;
}
reversed >>= 1;
while(reversed > 1) {
if((reversed & 1) == 0) {
node = node.left;
} else {
node = node.right;
}
reversed >>= 1;
}
return node;
}
public TreeNode<T> remove(int pos) {
if(pos <= 1) {
return null;
}
TreeNode<T> last = findNode(pos);
if(last.parent.right == last) {
last.parent.right = null;
} else {
last.parent.left = null;
}
this.val = last.val;
bubbleDown();
return null;
}
public void bubbleDown() {
TreeNode<T> node = this;
do {
TreeNode<T> left = node.left;
TreeNode<T> right = node.right;
if(left != null && right != null) {
T max = left.val.compareTo(right.val) > 0 ? left.val : right.val;
if(max.compareTo(node.val) > 0) {
if(left.val.equals(max)) {
left.val = node.val;
node.val = max;
node = left;
} else {
right.val = node.val;
node.val = max;
node = right;
}
} else {
break;
}
} else if(left != null) {
T max = left.val;
if(left.val.compareTo(node.val) > 0) {
left.val = node.val;
node.val = max;
node = left;
} else {
break;
}
} else {
break;
}
} while(true);
}
}
private TreeNode<K> root;
private int position;
PriorityQ(){
this.position = 1;
}
public void insert(K val) {
if(val == null) {
return;
}
if(root == null) {
this.position = 1;
root = new TreeNode<K>(val);
this.position++;
return ;
}
root.insert(val, position);
position++;
}
public K remove() {
if(root == null) {
return null;
}
K val = root.val;
root.remove(this.position-1);
this.position--;
if(position == 1) {
root = null;
}
return val;
}
public static void main(String[] args) {
PriorityQ<Integer> q = new PriorityQ<>();
System.out.println(q.remove());
q.insert(1);
q.insert(11);
q.insert(111);
q.insert(1111);
q.remove();
q.remove();
q.remove();
q.remove();
q.insert(2);
q.insert(4);
}
}

Categories