issues when managing multiple stacks - java

Investigating a solution to manage multiple stacks, posted the problem and code I am debugging. The question is, why function popAt(int index) shift from bottom of next sub-stack? Does it because of the next element (in the order of stack push) of top of sub-stack 1, is bottom element of sub-stack 2? I am not sure if this behavior is correct, and whether the expected behavior is, after pop element of stack 1, the next element to pop is the element in stack 1 which is under previous top, other than bottom of next stack?
Imagine a (literal) stack of plates. If the stack gets too high, it might topple. Therefore, in real life, we would likely start a new stack when the previous stack exceeds some threshold. A data structure SetOfStacks that mimics this. SetOfStacks should be composed of several stacks, and should create a new stack once the previous one exceeds capacity. SetOfStacks.push() and SetOfStacks.pop() should behave identically to a single stack (that is, pop() should return the same values as it would if there were just a single stack), and function popAt(int index) which performs a pop operation on a specific sub-stack.
public class SetOfStacks {
ArrayList<Stack> stacks = new ArrayList<>();
public int capacity;
public SetOfStacks(int capacity) {
this.capacity = capacity;
}
public Stack getLastStack() {
if (stacks.size() == 0) return null;
return stacks.get(stacks.size() - 1);
}
public void push(int v) { /* see earlier code */
}
public int pop() {
Stack last = getLastStack();
System.out.println(stacks.size());
int v = last.pop();
if (last.size == 0) stacks.remove(stacks.size() - 1);
return v;
}
public int popAt(int index) {
return leftShift(index, true);
}
public int leftShift(int index, boolean removeTop) {
Stack stack = stacks.get(index);
int removed_item;
if (removeTop) removed_item = stack.pop();
else removed_item = stack.removeBottom();
if (stack.isEmpty()) {
stacks.remove(index);
} else if (stacks.size() > index + 1) {
int v = leftShift(index + 1, false);
stack.push(v);
}
return removed_item;
}
}
public class Stack {
private int capacity;
public Node top, bottom;
public int size = 0;
public Stack(int capacity) {
this.capacity = capacity;
}
public boolean isAtCapacity() {
return capacity == size;
}
public void join(Node above, Node below) {
if (below != null) below.above = above;
if (above != null) above.below = below;
}
public boolean push(int v) {
if (size >= capacity) return false;
size++;
Node n = new Node(v);
if (size == 1) bottom = n;
join(n, top);
top = n;
return true;
}
public int pop() {
Node t = top;
top = top.below;
size--;
return t.value;
}
public boolean isEmpty() {
return size == 0;
}
public int removeBottom() {
Node b = bottom;
bottom = bottom.above;
if (bottom != null) bottom.below = null;
size--;
return b.value;
}
}
thanks in advance,
Lin

leftShift() in your code may be called recursively with increasing index, that's why if you call it with index of 1 it may pop from stack #2 then (and, in a case when all stacks were 1 element in size, it will continue with stack #3, #4 and so on :( )

Here is my simple solution of stacks of plate using linkedList in java.
class Stack<T>{
Node top;
NodeTop nodeTop;
int count = 1;
int i = 3;
static class Node<T>{
private T data;
private Node next;
Node(T data){
this.data = data;
next = null;
}
}
static class NodeTop<T>{
private Node<T> top;
private NodeTop<T> next;
NodeTop(Node top){
this.top = top;
}
}
public void push(T data){
if(count > i){
System.out.println("Starting new row of plates");
NodeTop temp = new NodeTop(top);
temp.next = nodeTop;
nodeTop = temp;
top = null;
i = i + 3;
}
Node temp = new Node(data);
temp.next = top;
top = temp;
count++;
System.out.println(data);
}
public void pop(){
if(top == null){
System.out.println("Current row does not contains any plates, moving to next row");
if(nodeTop == null){
System.out.println("No Plates left");
return;
}
top = nodeTop.top;
nodeTop = nodeTop.next;
i = i - 3;
}
System.out.println(top.data);
top = top.next;
count--;
}
}

Related

get kth-largest-element-in-an-array - implemented using maxheap but getting time exceeded in leetcode

I am trying to solve this leetcode challenge . I implemented a MaxHeap and tried to popout the values to get the Kth largest element in the array but I get a time limit exceeded.
Is there any issue with my MaxHeap implementation that it is slow or can this be done in a faster method?
Problem
https://leetcode.com/problems/kth-largest-element-in-an-array/
class Solution {
private int capacity = 10;
private int size = 0;
int items [] = new int[capacity];
//parent = (i-1)/2
//left-child = 2i+1
//right-child = 2i
public int findKthLargest(int[] nums, int k) {
for(int i=0;i<nums.length;i++){
push(nums[i]);
}
//printHeapArray();
for(int i=0; i<k-1; i++){
int val = pop();
System.out.println("max val popped" + val);
// printHeapArray();
}
return peek();
}
private int getLeftChildIndex(int index){
return index*2+1;
}
private int getRightChildIndex(int index) {
return index*2;
}
private int getParentIndex(int index) {
return (index-1)/2;
}
private int leftChild(int index) {
return items[getLeftChildIndex(index)];
}
private int rightChild(int index) {
return items[getRightChildIndex(index)];
}
private int parent(int index) {
return items[getParentIndex(index)];
}
private boolean hasParent(int index){
return getParentIndex(index) >= 0;
}
private boolean hasLeftChild(int index){
return getLeftChildIndex(index) < size;
}
private boolean hasRightChild(int index){
return getRightChildIndex(index) < size;
}
private void swap(int indexOne, int indexTwo) {
int temp = items[indexOne];
items[indexOne] = items[indexTwo];
items[indexTwo] = temp;
}
private void ensureCapacity() {
if(capacity == size -1) {
items = Arrays.copyOf(items, capacity*2);
capacity *= 2;
}
}
public int peek() {
if(size == 0) {
throw new IllegalStateException();
}
return items[0];
}
public void push(int item) {
ensureCapacity();
items[size] = item;
size++;
heapifyUp();
}
private void heapifyUp() {
int index = size - 1;
while(hasParent(index) && parent(index) < items[index]) {
swap(getParentIndex(index), index);
index = getParentIndex(index);
}
}
public int pop() {
if(size == 0 ) throw new IllegalStateException();
int item = items[0];
items[0] = items[size-1];
size--;
heapifyDown();
return item;
}
//1.Compare the children first and find the child you want to compare against with parent
//2.Compare the selected child with its parent to see if it needs to be swapped
private void heapifyDown() {
int index = 0;
while(hasLeftChild(index))
{
int smallerChildIndex = getLeftChildIndex(index);
if(hasRightChild(index) && rightChild(index) > leftChild(index)){
smallerChildIndex = getRightChildIndex(index);
}
if(items[index] > items[smallerChildIndex]) {
break;
}
if(items[smallerChildIndex] > items[index]) {
swap(smallerChildIndex, index);
}
index = smallerChildIndex;
}
}
public void printHeapArray(){
System.out.println(Arrays.toString(items));
}
}
You have an infinite loop, because you're using the wrong formulas for left-child-index and right-child-index.
Look at heapifyDown. The first index tested is 0, and getRightChildIndex() says that it's right child is also at 0*2 == 0.
For heaps with the root at 0, the left and right children of i are at i*2+1 and i*2+2. For heaps with the root at 1 (not your case), the left and right children of i are at i*2 and i*2+1.
Note that if you fix this then your algorithm can work, but it won't be awesome. Appropriate solutions for this problem use quickselect (expected O(n)), a min-heap (O(n * log k)), or a partial heapsort (O(n + k log n)). Yours is like a partial heap sort, but without the O(n) heapify at the start, giving O(n log n).

How to write recursion get methods in doubly linkedlist?

here is my code
public class LinkedListDeque<T> implements Deque {
private Node sentinel;
private int size;
private static class Node<T> {
private T item;
private Node pre;
private Node next;
public Node(T i, Node p, Node n) {
item = i;
pre = p;
next = n;
}
public LinkedListDeque() {
size = 0;
sentinel = new Node(null, null, null);
sentinel.next = sentinel;
sentinel.pre = sentinel;
}
public LinkedListDeque(T item) {
size = 1;
Node first = new Node(item, sentinel, sentinel);
sentinel = new Node(null, first, first);
}
public Object getRecursive(int index) {}
}
I just can't figure out how to do it. I can do it in a interation way. I don't know where to start to build a recursion methods.
public Node getNode(Node n, int index, int pos) {
if (index == pos) {
return n;
}
if (index > pos || n == null) {
return null;
}
return getNode(n.next, index, pos++);
}
I believe this is what you want, and the initial call is with pos=0 and the head of the LinkedList.
I think you need to look up how recursion works though, because you failed to even attempt the problem.

Trouble searching a Stack in Java

I'm having trouble with programming a function in Java.
First i have implemented a Stack through a Single Linked List, like this:
public class ListStack<E> implements Stack<E> {
private static class Node<T> {
private T item;
private Node<T> next;
private Node(T item, Node<T> next) {
this.item = item;
this.next = next;
}
}
private Node<E> first;
private int size;
public ListStack() {
this.size = 0;
this.first = null;
}
#Override
public E peek() {
return first.item;
}
#Override
public void pop() {
first = first.next;
size--;
}
#Override
public void push(E e) {
Node<E> node = new Node<E>(e, first);
first = node;
size++;
}
#Override
public boolean isEmpty() {
return (first == null);
}
#Override
public int size() {
return size;
}
#Override
public Stack<E> reverse(){
ListStack<E> reversed = new ListStack<E>();
Node<E> node = first;
while(node != null){
reversed.push(node.item);
node = node.next;
}
return reversed;
}
}
Then i have created a stackof a type X. Here's that type's definition and constructor:
private String first, second;
private ListStack<String> text;
public X(String first, String second){
this.first = first;
this.second = second;
this.text = new ListStack<String>();
}
There are getters for both the strings firstand second, getFirst(), and getSecond(), respectively.
Then i want to write a function that basically, for each X of the stack, checks if the String second is equal to the String txt, passed as the function's argument. If it is, it returns X and deletes the Node from the stack, otherwise just returns null.
Here's my implementation of the method:
First, as a private attribute of the class:
private Stack<X> text; //for simplicity, let's assume the stack already contains values of type `X`.
Then:
private X getX(String txt) {
Stack<X> stack = text.reverse();
Stack<X> stack_final = new ListStack<X>();
X c;
String txt2;
boolean found = false;
for (int i = 0; i < stack.size() && !found; i++) {
c = stack.peek(); //extracts the element
txt2 = c.getSecond(); //gets the name
if (txt2.equals(txt)) {
found = true;
stack.pop();
} else
stack_final.push(c);
stack.pop();
}
if (found) {
text = stack_final;
return c;
}
else
return null;
}
What am i doing wrong ?
My guess is that i'm not updating the final stack correctly, with only the values that don't check, but i'm not sure it is that...
The main problem is the for-loop. Just step through it in your head:
i=0 stack=[1,2,3,4,5,6] stack_size=6
i=1 stack=[2,3,4,5,6] stack_size=5
i=2 stack=[3,4,5,6] stack_size=4
i=3 stack=[4,5,6] stack_size=3
the code actually breaks off after reading only half of the stack. You should rather use isEmpty() than a counter.
private X getX(String txt){
Stack<X> stack = text.reverse();
Stack<X> stack_final = new ListStack<X>();
X c = null;
while(!stack.isEmpty()){//transfer all items from stack to stack_final
//retrive and remove the first item from stack
X x = stack.peek();
stack.pop();
if(x.getSecond().equals(txt))//save x as searched item, if it matches
c = x;
//add the item to stack_final
stack_final.push(x);
}
//save stack_final as text (stack_final is a copy of text)
text = stack_final;
//c is either the searched item, or null, if no item was found
return c;
}
And btw., it's common that pop() returns the removed element.
public X pop(){
X res = first.item;
first = first.next;
return res;
}
You will get a NullPointerException if you try to peek() or pop() an empty stack!
public E peek() {
return first.item; // first is null if stack is empty!
}
public void pop() {
first = first.next; // first is null if stack is empty!
size--;
}
The Java Stack class throws an EmptyStackException in those cases.
Then I want to write a function that basically, for each X of the stack, checks if the String second is equal to the String txt, passed as the function's argument. If it is, it returns X and deletes the Node from the stack, otherwise just returns null.
Now, to achieve what you asked, you can simply do:
Stack<X> stack = text.reversed();
X elementFound = null;
while (!stack.isEmpty()) {
if (txt.equals(stack.peek().getSecond()) {
elementFound = stack.peek();
} else {
stackCopy.push(stack.peek());
}
stack.pop();
}
// now stack is empty and stackCopy contains stack reversed and without
// elementFound, if elementFound is not null (meaning it was found)
text = stackCopy; // stack was text reversed
return elementFound;

Recursively find nth to last element in linked list

I'm practicing basic data structure stuff and I'm having some difficulties with recursion. I understand how to do this through iteration but all of my attempts to return the nth node from the last of a linked list via recursion result in null. This is my code so far:
public static int i = 0;
public static Link.Node findnthToLastRecursion(Link.Node node, int pos) {
if(node == null) return null;
else{
findnthToLastRecursion(node.next(), pos);
if(++i == pos) return node;
return null;
}
Can anyone help me understand where I'm going wrong here?
This is my iterative solution which works fine, but I'd really like to know how to translate this into recursion:
public static Link.Node findnthToLast(Link.Node head, int n) {
if (n < 1 || head == null) {
return null;
}
Link.Node pntr1 = head, pntr2 = head;
for (int i = 0; i < n - 1; i++) {
if (pntr2 == null) {
return null;
} else {
pntr2 = pntr2.next();
}
}
while (pntr2.next() != null) {
pntr1 = pntr1.next();
pntr2 = pntr2.next();
}
return pntr1;
}
You need to go to the end and then count your way back, make sure to pass back the node each time its passed back. I like one return point
public static int i = 0;
public static Link.Node findnthToLastRecursion(Link.Node node, int pos) {
Link.Node result = node;
if(node != null) {
result = findnthToLastRecursion(node.next, pos);
if(i++ == pos){
result = node;
}
}
return result;
}
Working example outputs 7 as 2 away from the 9th and last node:
public class NodeTest {
private static class Node<E> {
E item;
Node<E> next;
Node<E> prev;
Node(Node<E> prev, E element, Node<E> next) {
this.item = element;
this.next = next;
this.prev = prev;
}
}
/**
* #param args
*/
public static void main(String[] args) {
Node first = null;
Node prev = null;
for (int i = 0; i < 10; i++) {
Node current = new Node(prev, Integer.toString(i),null);
if(i==0){
first = current;
}
if(prev != null){
prev.next = current;
}
prev = current;
}
System.out.println( findnthToLastRecursion(first,2).item);
}
public static int i = 0;
public static Node findnthToLastRecursion(Node node, int pos) {
Node result = node;
if (node != null) {
result = findnthToLastRecursion(node.next, pos);
if (i++ == pos) {
result = node;
}
}
return result;
}
}
No need for static variables.
public class List {
private Node head = null;
// [...] Other methods
public Node findNthLastRecursive(int nth) {
if (nth <= 0) return null;
return this.findNthLastRecursive(this.head, nth, new int[] {0});
}
private Node findNthLastRecursive(Node p, int nth, int[] pos) {
if (p == null) {
return null;
}
Node n = findNthLastRecursive(p.next, nth, pos);
pos[0]++;
if (pos[0] == nth) {
n = p;
}
return n;
}
}
You can do this a couple of ways:
recurse through the list once to find the list length, then write a recursive method to return the kth element (a much easier problem).
use an auxiliary structure to hold the result plus the remaining length; this essentially replaces the two recursions of the first option with a single recursion:
static class State {
Link.Node result;
int trailingLength;
}
public static Link.Node findnthToLastRecursion(Link.Node node, int pos) {
if(node == null) return null;
State state = new State();
findnthToLastRecursion(node, pos, state);
return state.result;
}
private static void findnthToLastRecursion(Link.Node node, int pos, State state) {
if (node == null) {
state.trailingLength = 0;
} else {
findnthToLastRecursion(node.next(), state);
if (pos == state.trailingLength) {
state.result = node;
}
++state.trailingLength;
}
}
I misunderstood the question. Here is an answer based on your iterative solution:
public static Link.Node findnthToLast(Link.Node head, int n) {
return findnthToLastHelper(head, head, n);
}
private static Link.Node findnthToLastHelper(Link.Node head, Link.Node end, int n) {
if ( end == null ) {
return ( n > 0 ? null : head);
} elseif ( n > 0 ) {
return findnthToLastHelper(head, end.next(), n-1);
} else {
return findnthToLastHelper(head.next(), end.next(), 0);
}
}
actually you don't need to have public static int i = 0; . for utill method the pos is :
pos = linked list length - pos from last + 1
public static Node findnthToLastRecursion(Node node, int pos) {
if(node ==null){ //if null then return null
return null;
}
int length = length(node);//find the length of the liked list
if(length < pos){
return null;
}
else{
return utill(node, length - pos + 1);
}
}
private static int length(Node n){//method which finds the length of the linked list
if(n==null){
return 0;
}
int count = 0;
while(n!=null){
count++;
n=n.next;
}
return count;
}
private static Node utill(Node node, int pos) {
if(node == null) {
return null;
}
if(pos ==1){
return node;
}
else{
return utill(node.next, pos-1);
}
}
Here node.next is the next node. I am directly accessing the next node rather than calling the next() method. Hope it helps.
This cheats (slightly) but it looks good.
public class Test {
List<String> list = new ArrayList<> (Arrays.asList("Zero","One","Two","Three","Four","Five","Six","Seven","Eight","Nine","Ten"));
public static String findNthToLastUsingRecursionCheatingALittle(List<String> list, int n) {
int s = list.size();
return s > n
// Go deeper!
? findNthToLastUsingRecursionCheatingALittle(list.subList(1, list.size()), n)
// Found it.
: s == n ? list.get(0)
// Too far.
: null;
}
public void test() {
System.out.println(findNthToLastUsingRecursionCheating(list,3));
}
public static void main(String args[]) {
new Test().test();
}
}
It prints:
Eight
which I suppose is correct.
I have use List instead of some LinkedList variant because I do not want to reinvent anything.
int nthNode(struct Node* head, int n)
{
if (head == NULL)
return 0;
else {
int i;
i = nthNode(head->left, n) + 1;
printf("=%d,%d,%d\n", head->data,i,n);
if (i == n)
printf("%d\n", head->data);
}
}
public class NthElementFromLast {
public static void main(String[] args) {
List<String> list = new LinkedList<>();
Stream.of("A","B","C","D","E").forEach(s -> list.add(s));
System.out.println(list);
System.out.println(getNthElementFromLast(list,2));
}
private static String getNthElementFromLast(List list, int positionFromLast) {
String current = (String) list.get(0);
int index = positionFromLast;
ListIterator<String> listIterator = list.listIterator();
while(positionFromLast>0 && listIterator.hasNext()){
positionFromLast--;
current = listIterator.next();
}
if(positionFromLast != 0) {
return null;
}
String nthFromLast = null;
ListIterator<String> stringListIterator = list.listIterator();
while(listIterator.hasNext()) {
current = listIterator.next();
nthFromLast = stringListIterator.next();
}
return nthFromLast;
}
}
This will find Nth element from last.
My approach is simple and straight,you can change the array size depending upon your requirement:
int pos_from_tail(node *k,int n)
{ static int count=0,a[100];
if(!k) return -1;
else
pos_from_tail(k->next,n);
a[count++]=k->data;
return a[n];
}
You'll have make slight changes in the code:
public static int i = 0;
public static Link.Node findnthToLastRecursion(Link.Node node, int pos) {
if(node == null) return null;
else{
**Link.Node temp = findnthToLastRecursion(node.next(), pos);
if(temp!=null)
return temp;**
if(++i == pos) return node;
return null;
}
}

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