heap data structure via pointers - data-structures

Suggest an efficient way to find last position in heap satisfying the following conditions:
1) via pointers not via array
2) where we can insert or delete node
I could find it in O(n) time complexity but suggest a way which is of O(logn) or O(1) time complexity.

I'm assuming here that you mean a binary heap.
If you know how many nodes are in the heap, you can find the last node in O(log n) time by converting the count to binary, and then following the path of bits from high to low. That is, take the left node if the bit is 0, and the right node if the bit is 1.
For example, if there are three nodes in the heap, the binary representation of the count is 11. The root is always the first node, leaving you with 1. Then you take the right branch to get the last node.
Say there are 5 nodes in the heap:
1
2 3
4 5
In binary, that's 101. So you take the root. The next digit is 0 so you take the left branch. The next digit is 1, so you take the right branch, leaving you at node 5.
If you want the next available slot, you add 1 to the count and do the same thing. So 6 would be 110. You take the root, then the right branch, and the left child of 3 is where you'd add the new node.
You can do the same kind of thing with any d-ary heap, except that instead of converting to binary you convert to base d. So if your heap nodes each have up to three children, you'd convert the count to base 3, and use essentially the same logic as above.
An alternative is to maintain a reference to the last node in the heap, updating it every time you modify the heap. Or, if you want to know where the next node would be placed, you maintain a reference to the first node that doesn't have two children. That's O(1), but requires bookkeeping on every insertion or deletion.

I am answering my own question, There is no need to keep track of next pointer while inserting in heap (heap via pointers), even there is no need to keep track of parent, i am attaching running java code for heap, all possible method are included in it, getMin() = O(1), insert() = O(logn), extractMin = O(logn), decreasePriorityOfHead = O(logn), I have implemented it for generic code so it would be helpful to understand generic concept also.
class MinHeap<E extends Comparable<E>> {
private DoublyNode<E> root;
private int size = 0;
public DoublyNode<E> getRoot() {
return root;
}
public void setRoot(DoublyNode<E> root) {
this.root = root;
}
public int getSize() {
return size;
}
public void setSize(int size) {
this.size = size;
}
public MinHeap() {
}
public MinHeap(E data) {
this.root = new DoublyNode<E>(data);
this.size++;
}
private class NodeLevel<E extends Comparable<E>> {
private int level;
private DoublyNode<E> node;
public int getLevel() {
return level;
}
public void setLevel(int level) {
this.level = level;
}
public DoublyNode<E> getNode() {
return node;
}
public void setNode(DoublyNode<E> node) {
this.node = node;
}
public NodeLevel(DoublyNode<E> node, int level) {
this.node = node;
this.level = level;
}
}
public void insert(E data) {
if (this.size == 0) {
this.root = new DoublyNode<E>(data);
this.size++;
return;
}
DoublyNode<E> tempRoot = this.root;
Integer insertingElementPosition = this.size + 1;
char[] insertingElementArray = Integer.toBinaryString(
insertingElementPosition).toCharArray();
DoublyNode<E> newNode = new DoublyNode<E>(data);
int i;
for (i = 1; i < insertingElementArray.length - 1; i++) {
if (newNode.getData().compareTo(tempRoot.getData()) < 0) {
this.swap(newNode, tempRoot);
}
char c = insertingElementArray[i];
if (c == '0') {
tempRoot = tempRoot.getLeft();
} else {
tempRoot = tempRoot.getRight();
}
}
// newNode.setParent(tempRoot);
if (newNode.getData().compareTo(tempRoot.getData()) < 0) {
this.swap(newNode, tempRoot);
}
if (insertingElementArray[i] == '0') {
tempRoot.setLeft(newNode);
} else {
tempRoot.setRight(newNode);
}
this.size++;
}
public void swap(DoublyNode<E> node1, DoublyNode<E> node2) {
E temp = node1.getData();
node1.setData(node2.getData());
node2.setData(temp);
}
public E getMin() {
if (this.size == 0) {
return null;
}
return this.root.getData();
}
public void heapifyDownWord(DoublyNode<E> temp) {
if (temp == null) {
return;
}
DoublyNode<E> smallerChild = this.getSmallerChild(temp);
if (smallerChild == null) {
return;
}
if (smallerChild.getData().compareTo(temp.getData()) < 0) {
this.swap(temp, smallerChild);
this.heapifyDownWord(smallerChild);
}
}
public DoublyNode<E> getSmallerChild(DoublyNode<E> temp) {
if (temp.getLeft() != null && temp.getRight() != null) {
return (temp.getLeft().getData()
.compareTo(temp.getRight().getData()) < 0) ? temp.getLeft()
: temp.getRight();
} else if (temp.getLeft() != null) {
return temp.getLeft();
} else {
return temp.getRight();
}
}
public E extractMin() {
if (this.root == null) {
return null;
}
E temp = this.root.getData();
if (this.root.getLeft() == null && this.root.getRight() == null) {
this.root = null;
this.size--;
return temp;
}
DoublyNode<E> parentOfLastData = this.getParentOfLastData();
if (parentOfLastData.getRight() != null) {
this.root.setData(parentOfLastData.getRight().getData());
parentOfLastData.setRight(null);
} else {
this.root.setData(parentOfLastData.getLeft().getData());
parentOfLastData.setLeft(null);
}
this.heapifyDownWord(this.root);
return temp;
}
public DoublyNode<E> getParentOfLastData() {
if (this.size == 0) {
return null;
}
DoublyNode<E> tempRoot = this.root;
Integer insertingElementPosition = this.size;
char[] insertingElementArray = Integer.toBinaryString(
insertingElementPosition).toCharArray();
int i;
for (i = 1; i < insertingElementArray.length - 1; i++) {
char c = insertingElementArray[i];
if (c == '0') {
tempRoot = tempRoot.getLeft();
} else {
tempRoot = tempRoot.getRight();
}
}
return tempRoot;
}
public DoublyNode<E> getParentOfLastEmptyPosition() {
if (this.size == 0) {
return null;
}
DoublyNode<E> tempRoot = this.root;
Integer insertingElementPosition = this.size + 1;
char[] insertingElementArray = Integer.toBinaryString(
insertingElementPosition).toCharArray();
System.out.println(insertingElementArray.toString());
int i;
for (i = 1; i < insertingElementArray.length - 1; i++) {
char c = insertingElementArray[i];
if (c == '0') {
tempRoot = tempRoot.getLeft();
} else {
tempRoot = tempRoot.getRight();
}
}
return tempRoot;
}
public void print() {
if (this.root == null) {
System.out.println("Heap via pointer is empty!");
return;
}
System.out.println("\n Heap via pointer is:- ");
Queue<NodeLevel<E>> dataQueue = new Queue<NodeLevel<E>>();
Queue<Space> spaceQueue = new Queue<Space>();
dataQueue.enQueue(new NodeLevel<E>(this.root, 1));
int heightOfTree = this.getHeightOfHeap();
Double powerHeghtBST = Math.pow(heightOfTree, 2);
spaceQueue.enQueue(new Space(powerHeghtBST.intValue(), false));
while (!dataQueue.isEmpty()) {
Space space = spaceQueue.deQueue();
NodeLevel<E> nodeLevel = dataQueue.deQueue();
while (space.isNullSpace()) {
space.printNullSpace();
spaceQueue.enQueue(space);
space = spaceQueue.deQueue();
}
space.printFrontSpace();
System.out.print(nodeLevel.getNode().getData().printingData());
space.printBackSpace();
if (nodeLevel.getNode().getLeft() != null) {
dataQueue.enQueue(new NodeLevel<E>(nodeLevel.getNode()
.getLeft(), nodeLevel.getLevel() + 1));
spaceQueue.enQueue(new Space(space.getSpaceSize() / 2, false));
} else {
spaceQueue.enQueue(new Space(space.getSpaceSize() / 2, true));
}
if (nodeLevel.getNode().getRight() != null) {
dataQueue.enQueue(new NodeLevel<E>(nodeLevel.getNode()
.getRight(), nodeLevel.getLevel() + 1));
spaceQueue.enQueue(new Space(space.getSpaceSize() / 2, false));
} else {
spaceQueue.enQueue(new Space(space.getSpaceSize() / 2, true));
}
if (!dataQueue.isEmpty()
&& nodeLevel.getLevel() + 1 == dataQueue.getFrontData()
.getLevel()) {
System.out.println("\n");
}
}
}
public int getHeightOfHeap() {
if (this.size == 0) {
return 0;
}
Double height = Math.log(this.size) / Math.log(2) + 1;
return height.intValue();
}
public void changePriorityOfHeapTop(E data) {
if (this.root == null) {
return;
}
this.root.setData(data);
this.heapifyDownWord(this.root);
}
}
interface Comparable<T> extends java.lang.Comparable<T> {
/**
* this methos returns a string of that data which to be shown during
* printing tree
*
* #return
*/
public String printingData();
}
public class PracticeMainClass {
public static void main(String[] args) {
MinHeap<Student> minHeap1 = new MinHeap<Student>();
minHeap1.insert(new Student(50, "a"));
minHeap1.insert(new Student(20, "a"));
minHeap1.insert(new Student(60, "a"));
minHeap1.insert(new Student(30, "a"));
minHeap1.insert(new Student(40, "a"));
minHeap1.insert(new Student(70, "a"));
minHeap1.insert(new Student(10, "a"));
minHeap1.insert(new Student(55, "a"));
minHeap1.insert(new Student(35, "a"));
minHeap1.insert(new Student(45, "a"));
minHeap1.print();
minHeap1.getMin();
minHeap1.print();
System.out
.println("\nminimum is:- " + minHeap1.getMin().printingData());
minHeap1.print();
System.out.println("\nminimum is:- "
+ minHeap1.extractMin().printingData());
minHeap1.print();
minHeap1.changePriorityOfHeapTop(new Student(75, "a"));
minHeap1.print();
}
}
class DoublyNode<E extends Comparable<E>> {
private E data;
private DoublyNode<E> left;
private DoublyNode<E> right;
// private DoublyNode<E> parent;
public DoublyNode() {
}
public DoublyNode(E data) {
this.data = data;
}
public E getData() {
return data;
}
public void setData(E data) {
this.data = data;
}
public DoublyNode<E> getLeft() {
return left;
}
public void setLeft(DoublyNode<E> left) {
this.left = left;
}
public DoublyNode<E> getRight() {
return right;
}
public void setRight(DoublyNode<E> right) {
this.right = right;
}
// public DoublyNode<E> getParent() {
// return parent;
// }
// public void setParent(DoublyNode<E> parent) {
// this.parent = parent;
// }
}
class Space {
private boolean isNullSpace = false;
private String frontSpace;
private String backSpace;
private String nullSpace;
private int spaceSize;
public boolean isNullSpace() {
return isNullSpace;
}
public void setNullSpace(boolean isNullSpace) {
this.isNullSpace = isNullSpace;
}
public int getSpaceSize() {
return spaceSize;
}
public void setSpaceSize(int spaceSize) {
this.spaceSize = spaceSize;
}
public Space(int spaceSize, boolean isNullSpace) {
this.isNullSpace = isNullSpace;
this.spaceSize = spaceSize;
if (spaceSize == 0) {
this.frontSpace = "";
this.backSpace = "";
this.nullSpace = " ";
} else if (spaceSize == 1) {
this.frontSpace = " ";
this.backSpace = "";
this.nullSpace = " ";
} else if (spaceSize == 2) {
this.frontSpace = " ";
this.backSpace = "";
this.nullSpace = " ";
} else {
this.frontSpace = String.format("%" + (spaceSize) + "s", " ");
this.backSpace = String.format("%" + (spaceSize - 2) + "s", " ");
this.nullSpace = String.format("%" + 2 * (spaceSize) + "s", " ");
}
}
public void printFrontSpace() {
System.out.print(this.frontSpace);
}
public void printBackSpace() {
System.out.print(this.backSpace);
}
public void printNullSpace() {
System.out.print(this.nullSpace);
}
}
class Queue<E> {
private Node<E> front;
private Node<E> rear;
private int queueSize = 0;
public Queue() {
}
public Queue(E data) {
this.front = new Node(data);
this.rear = this.front;
}
public void enQueue(E data) {
if (this.rear == null) {
this.rear = new Node(data);
this.front = this.rear;
} else {
Node newNode = new Node(data);
this.rear.setNext(newNode);
this.rear = newNode;
}
this.queueSize++;
}
public E deQueue() {
E returnValue;
if (this.front == null) {
return null;
} else if (this.front == this.rear) {
returnValue = this.front.getData();
this.front = null;
this.rear = null;
} else {
returnValue = this.front.getData();
this.front = this.front.getNext();
}
this.queueSize--;
return returnValue;
}
public void print() {
Node temp = this.front;
System.out.print("\n Queue is:- ");
if (temp == null) {
System.out.println(" Empty! ");
}
while (temp != null) {
System.out.print(temp.getData() + ",");
temp = temp.getNext();
}
}
public int getQueueSize() {
return queueSize;
}
public E getFrontData() {
if (this.front == null) {
System.out.println("queue is empty!");
return null;
}
return this.front.getData();
}
public E getRearData() {
if (this.rear == null) {
System.out.println("queue is empty!");
return null;
}
return this.rear.getData();
}
public boolean isEmpty() {
return this.front == null;
}
}
class Node<E> {
private E data;
private Node next;
public Node(E data) {
this.data = data;
}
public E getData() {
return data;
}
public void setData(E data) {
this.data = data;
}
public Node getNext() {
return next;
}
public void setNext(Node next) {
this.next = next;
}
}
class Student implements Comparable<Student> {
private int id;
private String name;
#Override
public int compareTo(Student student) {
if (this.id == student.id) {
return 0;
} else if (this.id < student.id) {
return -1;
} else {
return 1;
}
}
public Student(int id, String name) {
this.id = id;
this.name = name;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
#Override
public String printingData() {
// String printingData = "{ id: "+this.id+" name: "+this.name+" }";
String printingData = String.valueOf(this.id);
return printingData;
}
}
Output of this code is:-
Heap via pointer is:-
10
30 20
35 40 70 60
55 50 45
Heap via pointer is:-
10
30 20
35 40 70 60
55 50 45
minimum is:- 10
Heap via pointer is:-
10
30 20
35 40 70 60
55 50 45
minimum is:- 10
Heap via pointer is:-
20
30 45
35 40 70 60
55 50
Heap via pointer is:-
30
35 45
50 40 70 60
55 75

Related

Shortest uncommon subseqence

Given two strings s and t, determine length of shortest string z such that z is a subsequence of s and not a subsequence of t.
example :
s :babab,
t :babba
sol :
3 (aab)
not looking for copy pastable code, please if anybody can help with intution for solving this.
thanks a lot !
Here you go. I created on IEnumarable method which gives back all possible combinations. This is compared with t. I optimized the solution to loop only once over the not match String t.
using System;
using System.Collections.Generic;
namespace GuessTheNumber
{
public class Element:IComparable<Element>
{
public string Seq { get; set; }
public int Id { get; set; }
public int CompareTo(Element other)
{
return this.Seq.CompareTo(other.Seq);
}
}
class Program
{
static void Main(string[] args)
{
string s = "babab";
string t = "babba";
string z = ShortestUncommonSuqsequence(s, t);
}
static public string ShortestUncommonSuqsequence(string SubSequenceOf, string NotSubSequenceOf)
{
var uniqueSeq = new SortedList<Element, int>();
uniqueSeq.Add(new Element() { Seq = "", Id = -1 }, -1);
foreach (Element oneSequence in GetNextUniqueSequences(uniqueSeq, SubSequenceOf))
{
int index = oneSequence.Id + 1;
while (index < NotSubSequenceOf.Length)
{
char NotChar = NotSubSequenceOf[index];
if (oneSequence.Seq[oneSequence.Seq.Length - 1] == NotChar) break;
index++;
}
if (index == NotSubSequenceOf.Length)
{
return oneSequence.Seq;
}
else
{
oneSequence.Id = index;
}
}
return null;
}
static public IEnumerable<Element> GetNextUniqueSequences(SortedList<Element, int> UniqueSeq, string Input)
{
SortedList<Element, int> results = new SortedList<Element, int>();
foreach (var prevResult in UniqueSeq)
{
for (int i = 0; i < Input.Length; i++)
{
if (prevResult.Value < prevResult.Key.Seq.Length + i)
{
string nextStr = prevResult.Key.Seq + Input[i].ToString();
Element newElem = new Element() { Seq = nextStr, Id = prevResult.Key.Id };
if (!results.Keys.Contains(newElem))
{
results.Add(newElem, prevResult.Key.Seq.Length + i);
yield return newElem;
}
}
}
}
if (Input.Length > 1)
{
foreach (Element res in GetNextUniqueSequences(results, Input.Substring(1)))
{
yield return res;
}
}
}
}
}

Insertion Sort for Singly Linked List [EXTERNAL]

I'm not sure where to start, but this is messy. Basically I need to write an Insertion Sort method for singly linked list - which causes enough problems, because usually for Insertion Sort - you're supposed to go through array/list elements backwards - which implementing into a singly linked list seems pointless, because the point of it - is that you're only capable of going forwards in the list and in addition to that -> I need to execute "swap" operations externally, which I do not completely understand how to perform that while using list structure.
This is my ArrayClass and Swap method that I used:
class MyFileArray : DataArray
{
public MyFileArray(string filename, int n, int seed)
{
double[] data = new double[n];
length = n;
Random rand = new Random(seed);
for (int i = 0; i < length; i++)
{
data[i] = rand.NextDouble();
}
if (File.Exists(filename)) File.Delete(filename);
try
{
using (BinaryWriter writer = new BinaryWriter(File.Open(filename,
FileMode.Create)))
{
for (int j = 0; j < length; j++)
writer.Write(data[j]);
}
}
catch (IOException ex)
{
Console.WriteLine(ex.ToString());
}
}
public FileStream fs { get; set; }
public override double this[int index]
{
get
{
Byte[] data = new Byte[8];
fs.Seek(8 * index, SeekOrigin.Begin);
fs.Read(data, 0, 8);
double result = BitConverter.ToDouble(data, 0);
return result;
}
}
public override void Swap(int j, double a)
{
Byte[] data = new Byte[16];
BitConverter.GetBytes(a).CopyTo(data, 0);
fs.Seek(8 * (j + 1), SeekOrigin.Begin);
fs.Write(data, 0, 8);
}
}
And this is my Insertion Sort for array:
public static void InsertionSort(DataArray items)
{
double key;
int j;
for (int i = 1; i < items.Length; i++)
{
key = items[i];
j = i - 1;
while (j >= 0 && items[j] > key)
{
items.Swap(j, items[j]);
j = j - 1;
}
items.Swap(j, key);
}
}
Now I somehow have to do the same exact thing - however using Singly Linked List, I'm given this kind of class to work with (allowed to make changes):
class MyFileList : DataList
{
int prevNode;
int currentNode;
int nextNode;
public MyFileList(string filename, int n, int seed)
{
length = n;
Random rand = new Random(seed);
if (File.Exists(filename)) File.Delete(filename);
try
{
using (BinaryWriter writer = new BinaryWriter(File.Open(filename,
FileMode.Create)))
{
writer.Write(4);
for (int j = 0; j < length; j++)
{
writer.Write(rand.NextDouble());
writer.Write((j + 1) * 12 + 4);
}
}
}
catch (IOException ex)
{
Console.WriteLine(ex.ToString());
}
}
public FileStream fs { get; set; }
public override double Head()
{
Byte[] data = new Byte[12];
fs.Seek(0, SeekOrigin.Begin);
fs.Read(data, 0, 4);
currentNode = BitConverter.ToInt32(data, 0);
prevNode = -1;
fs.Seek(currentNode, SeekOrigin.Begin);
fs.Read(data, 0, 12);
double result = BitConverter.ToDouble(data, 0);
nextNode = BitConverter.ToInt32(data, 8);
return result;
}
public override double Next()
{
Byte[] data = new Byte[12];
fs.Seek(nextNode, SeekOrigin.Begin);
fs.Read(data, 0, 12);
prevNode = currentNode;
currentNode = nextNode;
double result = BitConverter.ToDouble(data, 0);
nextNode = BitConverter.ToInt32(data, 8);
return result;
}
To be completely honest - I'm not sure neither how I'm supposed to implement Insertion Sort nor How then translate it into an external sort. I've used this code for not external sorting previously:
public override void InsertionSort()
{
sorted = null;
MyLinkedListNode current = headNode;
while (current != null)
{
MyLinkedListNode next = current.nextNode;
sortedInsert(current);
current = next;
}
headNode = sorted;
}
void sortedInsert(MyLinkedListNode newnode)
{
if (sorted == null || sorted.data >= newnode.data)
{
newnode.nextNode = sorted;
sorted = newnode;
}
else
{
MyLinkedListNode current = sorted;
while (current.nextNode != null && current.nextNode.data < newnode.data)
{
current = current.nextNode;
}
newnode.nextNode = current.nextNode;
current.nextNode = newnode;
}
}
So if someone could maybe give some kind of tips/explanations - or maybe if you have ever tried this - code examples how to solve this kind of problem, would be appreciated!
I actually have solved this fairly recently.
Here's the code sample that you can play around with, it should work out of the box.
public class SortLinkedList {
public static class LinkListNode {
private Integer value;
LinkListNode nextNode;
public LinkListNode(Integer value, LinkListNode nextNode) {
this.value = value;
this.nextNode = nextNode;
}
public Integer getValue() {
return value;
}
public void setValue(Integer value) {
this.value = value;
}
public LinkListNode getNextNode() {
return nextNode;
}
public void setNextNode(LinkListNode nextNode) {
this.nextNode = nextNode;
}
#Override
public String toString() {
return this.value.toString();
}
}
public static void main(String...args) {
LinkListNode f = new LinkListNode(12, null);
LinkListNode e = new LinkListNode(11, f);
LinkListNode c = new LinkListNode(13, e);
LinkListNode b = new LinkListNode(1, c);
LinkListNode a = new LinkListNode(5, b);
print(sort(a));
}
public static void print(LinkListNode aList) {
LinkListNode iterator = aList;
while (iterator != null) {
System.out.println(iterator.getValue());
iterator = iterator.getNextNode();
}
}
public static LinkListNode sort(LinkListNode aList){
LinkListNode head = new LinkListNode(null, aList);
LinkListNode fringePtr = aList.getNextNode();
LinkListNode ptrBeforeFringe = aList;
LinkListNode findPtr;
LinkListNode prev;
while(fringePtr != null) {
Integer valueToInsert = fringePtr.getValue();
findPtr = head.getNextNode();
prev = head;
while(findPtr != fringePtr) {
System.out.println("fringe=" + fringePtr);
System.out.println(findPtr);
if (valueToInsert <= findPtr.getValue()) {
LinkListNode tmpNode = fringePtr.getNextNode();
fringePtr.setNextNode(findPtr);
prev.setNextNode(fringePtr);
ptrBeforeFringe.setNextNode(tmpNode);
fringePtr = ptrBeforeFringe;
break;
}
findPtr = findPtr.getNextNode();
prev = prev.getNextNode();
}
fringePtr = fringePtr.getNextNode();
if (ptrBeforeFringe.getNextNode() != fringePtr) {
ptrBeforeFringe = ptrBeforeFringe.getNextNode();
}
}
return head.getNextNode();
}
}
From a high level, what you are doing is you are keeping track of a fringe ptr, and you are inserting a node s.t. the it is in the correct spot in the corresponding sublist.
For instance, suppose I have this LL.
3->2->5->4
The first iteration, I have fringePtr at 2, and I want to insert 2 somewhere in the sublist that's before the fringe ptr, so I basically traverse starting from head going to the fringe ptr until the value is less than the current value. I also have a previous keeping track of the previous ptr (to account for null, I have a sentinel node at the start of my traversal so I can insert it at the head).
Then, when I see that it's less than the current, I know I need to insert it next to the previous, so I have to:
use a temporary ptr to keep track of my previous's current next.
bind previuos's next to my toInsert node.
bind my toInsert node's next to my temp node.
Then, to continue, you just advance your fringe ptr and try again, basically building up a sublist that is sorted as you move along until fringe hits the end.
i.e. the iterations will look like
1. 3->2->5->4
^
2. 2->3->5->4
^
3. 2->3->5->4
^
4. 2->3->4->5 FIN.

Null pointer Exception while reversing a Queue using stack

I was practicing on how to implement queue using arrays. I have easily implemented how to enqueue and dequeue the elements in queue. But I have encountered an exception while implementing reverse of queue using stacks
public class QueueImpl {
private int capacity;
int queueArr[];
int front = 0;
int rear = -1;
int currentSize = 0;
QueueImpl(int queueSize){
this.capacity=queueSize;
queueArr=new int[this.capacity];
}
public void enqueue(int data){
if(isQueueFull()){
System.out.println("Overflow");
return;
}
else{
rear=rear+1;
if(rear==capacity-1)
{
rear=0;
}
queueArr[rear]=data;
currentSize++;
System.out.println("Element " + data+ " is pushed to Queue !");
}
}
public int dequeue(){
if(isQueueEmpty()){
System.out.println("UnderFlow");
}
else{
front=front+1;
if(front == capacity-1){
System.out.println("Pop operation done ! removed: "+queueArr[front-1]);
front = 0;
} else {
System.out.println("Pop operation done ! removed: "+queueArr[front-1]);
}
currentSize--;
}
return queueArr[front-1];
}
private boolean isQueueEmpty() {
boolean status=false;
if(currentSize==0){
status=true;
}
return status;
}
private boolean isQueueFull() {
boolean status=false;
if(currentSize==capacity){
status=true;
}
return status;
}
public static void main(String arg[]) {
QueueImpl queueImpl=new QueueImpl(5);
queueImpl.enqueue(5);
queueImpl.enqueue(2);
queueImpl.enqueue(9);
queueImpl.enqueue(1);
// queueImpl.dequeue();
queueImpl.printQueue(queueImpl);
queueImpl.reverse(queueImpl);
}
private void printQueue(QueueImpl queueImpl) {
System.out.println(queueImpl.toString());
}
#Override
public String toString() {
return "Queue [front=" + front + ", rear=" + rear + ", size=" + currentSize
+ ", queue=" + Arrays.toString(queueArr) + "]";
}
private QueueImpl reverse(QueueImpl queueImpl) throws ArrayIndexOutOfBoundsException {
int i=0;
Stack<Integer> stack=new Stack<Integer>();
while(!queueImpl.isQueueEmpty()){
stack.push(queueImpl.dequeue());
}
while(!stack.isEmpty()){
stack.get(i);
i++;
}
while(!stack.isEmpty()){
queueImpl.enqueue(stack.pop());
}
return queueImpl;
}
}
The error log is -
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: -1
at com.tcs.QueueUsingAraay.QueueImpl.dequeue(QueueImpl.java:51)
at com.tcs.QueueUsingAraay.QueueImpl.reverse(QueueImpl.java:93)
at com.tcs.QueueUsingAraay.QueueImpl.main(QueueImpl.java:78)
There was a problem in your dequeue method:
1. you were making front=0 and were trying to access front-1 which was -1
as a result the exception was thrown.
Removed stack.get as it was not required.
Corrected working code.
public class QueueImpl {
private int capacity;
int queueArr[];
int front = 0;
int rear = -1;
int currentSize = 0;
QueueImpl(int queueSize) {
this.capacity = queueSize;
queueArr = new int[this.capacity];
}
public void enqueue(int data) {
if (isQueueFull()) {
System.out.println("Overflow");
return;
} else {
rear = rear + 1;
if (rear == capacity - 1) {
rear = 0;
}
queueArr[rear] = data;
currentSize++;
System.out.println("Element " + data + " is pushed to Queue !");
}
}
public int dequeue() {
int element=-1;
if (isQueueEmpty()) {
System.out.println("UnderFlow");
} else {
element = queueArr[front];
front=front+1;
if (front == capacity - 1) {
System.out.println("Pop operation done ! removed: "
+ queueArr[front - 1]);
front = 0;
} else {
System.out.println("Pop operation done ! removed: "
+ queueArr[front - 1]);
}
currentSize--;
}
return element;
}
private boolean isQueueEmpty() {
boolean status = false;
if (currentSize == 0) {
status = true;
}
return status;
}
private boolean isQueueFull() {
boolean status = false;
if (currentSize == capacity) {
status = true;
}
return status;
}
public static void main(String arg[]) {
QueueImpl queueImpl = new QueueImpl(5);
queueImpl.enqueue(5);
queueImpl.enqueue(2);
queueImpl.enqueue(9);
queueImpl.enqueue(1);
queueImpl.printQueue(queueImpl);
queueImpl.reverse(queueImpl);
queueImpl.printQueue(queueImpl);
}
private void printQueue(QueueImpl queueImpl) {
System.out.println(queueImpl.toString());
}
#Override
public String toString() {
return "Queue [front=" + front + ", rear=" + rear + ", size="
+ currentSize + ", queue=" + Arrays.toString(queueArr) + "]";
}
private QueueImpl reverse(QueueImpl queueImpl)
throws ArrayIndexOutOfBoundsException {
Stack<Integer> stack = new Stack<Integer>();
while (!queueImpl.isQueueEmpty()) {
stack.push(queueImpl.dequeue());
}
while (!stack.isEmpty()) {
queueImpl.enqueue(stack.pop());
}
return queueImpl;
}
}

How to build a binary tree from a given interface

I need to build a simple binary tree, which includes Person elements.
Persons must be sorted by height(from low to high). If there are two people with same height, but different sex, men should be first. Usually we use left and right nodes of the element. How can I build tree otherways?
Here is how persons are created:
Person john = new Person() {
#Override
public boolean isMale() {
return true;
}
#Override
public int getID() {
return 1;
}
#Override
public int getHeight() {
return 175;
}
};
This is an interface:
public interface Person {
public int getID();
public boolean isMale();
public int getHeight();
}
Full code with test class
Node.java
public class Node {
double key = 0;
Node parent = null, left = null, right = null;
IDancer dancer = null;
public Node(IDancer d) {
this.dancer = d;
String key = d.getHeight() + (d.isMale() ? "0." : "1.") + d.getID();
this.key = Double.parseDouble(key);
System.out.println("new node: " + this.key);
}
public void copy(double key, IDancer d) {
this.dancer = d;
this.key = key;
}
public boolean hasRight() {
if (this.right != null) return true;
else return false;
}
public boolean hasLeft() {
if (this.left != null) return true;
else return false;
}
public boolean hasParent() {
if (this.parent != null) return true;
else return false;
}
public boolean isMale() {
if (this.dancer.isMale())
return true;
else return false;
}
}
Dancers.java
import java.util.AbstractMap.SimpleEntry;
import java.util.ArrayList;
import java.util.List;
public class Dancers implements IDancers {
public Tree tree = new Tree();
#Override
public SimpleEntry<IDancer, IDancer> findPartnerFor(IDancer d) throws IllegalArgumentException {
if (!(d instanceof IDancer) ||
(d.getHeight() <= 0) ||
(d.getID() <= 0)) throw new IllegalArgumentException();
IDancer partner = null;
tree.insert(d);
try {partner = (d.isMale()) ? tree.female(d) : tree.male(d);
} catch (NullPointerException n) {return null;}
if (partner != null) {
tree.remove(d);
tree.remove(partner);
System.err.println("Partner: "
+ d.getID()
+ (d.isMale() ? "M " : "F ")
+ " For: "
+ partner.getID()
+ (partner.isMale() ? "M " : "F "));
return new SimpleEntry<IDancer, IDancer>(d, partner);
} return null;
}
#Override
public List<IDancer> returnWaitingList() {
try {return tree.inorder(tree.root, new ArrayList<IDancer>());
} catch(NullPointerException n) {return new ArrayList<IDancer>();}
}
}
Tree.java
import java.util.ArrayList;
public class Tree {
public Node root = null;
public IDancer male(IDancer female) {
Node current = search(genKey(female));
Node tmp = succsessor(current);
while (!tmp.isMale()) {
tmp = succsessor(tmp);
} return tmp.isMale() ? tmp.dancer : null;
}
public IDancer female(IDancer male) {
Node current = search(genKey(male));
Node tmp = predecessor(current);
while (tmp.isMale()) {
tmp = predecessor(tmp);
} return tmp.isMale() ? null : tmp.dancer;
}
public Node minimum() {return minimum(this.root);}
private Node minimum(Node node) {
if (node.hasLeft())
return minimum(node.left);
else return node;
}
public Node maximum() {return maximum(this.root);}
public Node maximum(Node node) {
if (node.hasRight())
return maximum(node.right);
else return node;
}
public double genKey(IDancer d) {
return Double.parseDouble(d.getHeight() + (d.isMale() ? "0." : "1.") + d.getID());
}
private Node search(double key, Node current) {
if (current.key == key) return current;
if (current.key > key
&& current.hasLeft())
return search(key, current.left);
if (current.key < key
&& current.hasRight())
return search(key, current.right);
return null;
}
public Node search(double key) {return search(key, this.root);}
public void insert(IDancer d) {
Node dancer = new Node(d);
Node y = null;
if (root == null) {
this.root = dancer;
return;
}
Node x = this.root;
while (x != null) {
y = x;
if (dancer.key < x.key) x = x.left;
else x = x.right;
} dancer.parent = y;
if (y == null) this.root = dancer;
else {
if (dancer.key < y.key) y.left = dancer;
else y.right = dancer;
}
}
public ArrayList<IDancer> inorder(Node node, ArrayList<IDancer> output) {
if (node.hasLeft())
inorder(node.left, output);
output.add(node.dancer);
if (node.hasRight())
inorder(node.right, output);
return output;
}
public void remove(IDancer d) {
Node z = search(genKey(d)); //toRemove
Node y = null; //replacer
Node x = null;
if (!z.hasLeft() || !z.hasRight())
y = z;
else y = succsessor(z);
if (y.hasLeft())
x = y.left;
else x = y.right;
if (x != null)
x.parent = y.parent;
if (!y.hasParent())
this.root = x;
else if (y == y.parent.left)
y.parent.left = x;
else y.parent.right = x;
if (y != z)
z.dancer = y.dancer;
y = null;
}
private Node succsessor(Node n) {
if (n.hasRight())
return minimum(n.right);
Node tmp = n.hasParent() ? n.parent : null;
while (tmp != null && n == tmp.right) {
n = tmp;
tmp = tmp.parent;
} return tmp;
}
private Node predecessor(Node n) {
if (n.hasLeft())
return maximum(n.left);
Node tmp = n.hasParent() ? n.parent : null;
while (tmp != null && n == tmp.left) {
n = tmp;
tmp = tmp.parent;
} return tmp;
}
}

Optimizations for Solitaire SPOJ

Problem Code: SOLIT
Problem Link: http://www.spoj.com/problems/SOLIT/
I tried solving the SPOJ problem Solitaire. However, I ended up with a TLE (Time Limit Exceeded). My current solution is taking around 2 seconds to execute. I have no idea how to optimize my solution further in order to reduce the time. So, I would be grateful for any help in this regard.
Link to my solution: https://ideone.com/eySI91
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileDescriptor;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.Queue;
import java.util.StringTokenizer;
class Solitaire {
enum Direction {
TOP, RIGHT, DOWN, LEFT;
};
static class Piece {
int row, col;
public Piece(int row, int col) {
this.row = row;
this.col = col;
}
#Override
public boolean equals(Object o)
{
if (!(o instanceof Piece))
return false;
Piece p = (Piece)o;
return (row==p.row && col==p.col);
}
#Override
public int hashCode()
{
return (row*10 + col)%11;
}
}
static class State {
HashSet<Piece> pieces;
public State() {
pieces = new HashSet<>(11);
}
public State(State s) {
pieces = new HashSet<>(11);
for (Piece p: s.pieces)
pieces.add(new Piece(p.row, p.col));
}
#Override
public boolean equals(Object o) {
if (!(o instanceof State))
return false;
State s = (State) o;
if (pieces.size()!=s.pieces.size())
return false;
for (Piece p: pieces)
{
if (!s.pieces.contains(p))
return false;
}
return true;
}
#Override
public int hashCode() {
final int MOD = 1000000007;
long code = 0;
for (Piece p: pieces) {
code = (code + p.hashCode())%MOD;
}
return (int) code;
}
#Override
public String toString()
{
String res = "";
for (Piece p: pieces)
res = res + " (" + p.row + ", " + p.col + ")";
return res;
}
public int getCloseness(State s)
{
int medianRow=0, medianCol=0, sMedianRow=0, sMedianCol=0;
for (Piece p: pieces)
{
medianRow+=p.row;
medianCol+=p.col;
}
medianRow/=4;
medianCol/=4;
for (Piece p: s.pieces)
{
sMedianRow+=p.row;
sMedianCol+=p.col;
}
sMedianRow/=4;
sMedianCol/=4;
int closeness = ((sMedianCol-medianCol)*(sMedianCol-medianCol)) + ((sMedianRow-medianRow)*(sMedianRow-medianRow));
return closeness;
}
}
static State makeMove(State curr, Piece piece, Direction dir, HashSet<State> visited) {
if (dir == Direction.TOP) {
if (piece.row==1)
return null;
if (curr.pieces.contains(new Piece(piece.row-1, piece.col)))
{
if (piece.row==2 || curr.pieces.contains(new Piece(piece.row-2, piece.col)))
return null;
else
{
State newState = new State(curr);
newState.pieces.remove(new Piece(piece.row, piece.col));
newState.pieces.add(new Piece(piece.row-2, piece.col));
if (visited.contains(newState))
return null;
else
return newState;
}
}
else
{
State newState = new State(curr);
newState.pieces.remove(new Piece(piece.row, piece.col));
newState.pieces.add(new Piece(piece.row-1, piece.col));
if (visited.contains(newState))
return null;
else
return newState;
}
}
else if (dir == Direction.RIGHT) {
if (piece.col==8)
return null;
if (curr.pieces.contains(new Piece(piece.row, piece.col+1)))
{
if (piece.col==7 || curr.pieces.contains(new Piece(piece.row, piece.col+2)))
return null;
else
{
State newState = new State(curr);
newState.pieces.remove(new Piece(piece.row, piece.col));
newState.pieces.add(new Piece(piece.row, piece.col+2));
if (visited.contains(newState))
return null;
else
return newState;
}
}
else
{
State newState = new State(curr);
newState.pieces.remove(new Piece(piece.row, piece.col));
newState.pieces.add(new Piece(piece.row, piece.col+1));
if (visited.contains(newState))
return null;
else
return newState;
}
}
else if (dir == Direction.DOWN) {
if (piece.row==8)
return null;
if (curr.pieces.contains(new Piece(piece.row+1, piece.col)))
{
if (piece.row==7 || curr.pieces.contains(new Piece(piece.row+2, piece.col)))
return null;
else
{
State newState = new State(curr);
newState.pieces.remove(new Piece(piece.row, piece.col));
newState.pieces.add(new Piece(piece.row+2, piece.col));
if (visited.contains(newState))
return null;
else
return newState;
}
}
else
{
State newState = new State(curr);
newState.pieces.remove(new Piece(piece.row, piece.col));
newState.pieces.add(new Piece(piece.row+1, piece.col));
if (visited.contains(newState))
return null;
else
return newState;
}
}
else // dir == Direction.LEFT
{
if (piece.col==1)
return null;
if (curr.pieces.contains(new Piece(piece.row, piece.col-1)))
{
if(piece.col==2 || curr.pieces.contains(new Piece(piece.row, piece.col-2)))
return null;
else
{
State newState = new State(curr);
newState.pieces.remove(new Piece(piece.row, piece.col));
newState.pieces.add(new Piece(piece.row, piece.col-2));
if (visited.contains(newState))
return null;
else
return newState;
}
}
else
{
State newState = new State(curr);
newState.pieces.remove(new Piece(piece.row, piece.col));
newState.pieces.add(new Piece(piece.row, piece.col-1));
if (visited.contains(newState))
return null;
else
return newState;
}
}
}
static boolean isReachableInEightMoves(State src, State target) {
Queue<State> q = new LinkedList<>();
HashSet<State> visited = new HashSet<>();
int closeness = src.getCloseness(target);
q.add(src);
int moves = 0;
while (!q.isEmpty() && moves <= 8) {
int levelNodes = q.size();
for (int i = 0; i < levelNodes; i++) {
State curr = q.remove();
if (curr.equals(target))
return true;
if (moves==8)
continue;
visited.add(curr);
for (Piece p: curr.pieces)
{
State newState = makeMove(curr, p, Direction.TOP, visited);
if (newState!=null)
{
int newCloseness = newState.getCloseness(target);
if (closeness>=newCloseness)
{
closeness=newCloseness;
visited.add(newState);
q.add(newState);
}
}
newState = makeMove(curr, p, Direction.RIGHT, visited);
if (newState!=null)
{
int newCloseness = newState.getCloseness(target);
if (closeness>=newCloseness)
{
closeness=newCloseness;
visited.add(newState);
q.add(newState);
}
}
newState = makeMove(curr, p, Direction.DOWN, visited);
if (newState!=null)
{
int newCloseness = newState.getCloseness(target);
if (closeness>=newCloseness)
{
closeness=newCloseness;
visited.add(newState);
q.add(newState);
}
}
newState = makeMove(curr, p, Direction.LEFT, visited);
if (newState!=null)
{
int newCloseness = newState.getCloseness(target);
if (closeness>=newCloseness)
{
closeness=newCloseness;
visited.add(newState);
q.add(newState);
}
}
}
}
moves++;
}
return false;
}
public static void main(String[] args) throws IOException {
BufferedWriter out = new BufferedWriter(new OutputStreamWriter(
new FileOutputStream(FileDescriptor.out), "ASCII"));
CustomScanner sc = new CustomScanner();
int t = sc.nextInt();
long start = System.currentTimeMillis();
while (t-- > 0) {
State src = new State(), target = new State();
for (int i = 0; i < 4; i++) {
src.pieces.add(new Piece(sc.nextInt(), sc.nextInt()));
}
for (int i = 0; i < 4; i++) {
target.pieces.add(new Piece(sc.nextInt(), sc.nextInt()));
}
if (isReachableInEightMoves(src, target))
out.write("YES");
else
out.write("NO");
out.newLine();
}
long end = System.currentTimeMillis();
out.write("Time to execute = " + Double.toString((end-start)/1000d));
out.flush();
}
static class CustomScanner {
BufferedReader br;
StringTokenizer st;
public CustomScanner() {
br = new BufferedReader(new InputStreamReader(System.in));
}
private String next() {
while (st == null || !st.hasMoreElements()) {
try {
st = new StringTokenizer(br.readLine());
} catch (IOException e) {
e.printStackTrace();
}
}
return st.nextToken();
}
public int nextInt() {
return Integer.parseInt(next());
}
public long nextLong() {
return Long.parseLong(next());
}
public double nextDouble() {
return Double.parseDouble(next());
}
public String nextLine() {
String str = "";
try {
str = br.readLine();
} catch (IOException e) {
e.printStackTrace();
}
return str;
}
}
}
Some notes regarding the implementation:-
I am just doing a simple bfs traversal where each node is a state of
the board.
I have defined a function called getCloseness() which measures the closeness of two different states. It is basically the square of the distance between the centroids of the two states. A centroid of a state is the sum of all row values of each piece divided by 4 and the same for columns.
After calculating each state, I am checking if the closeness of this new state is lesser than or equal to the current closeness.
If it is not closer, then I will simply discard the new discovered state.
If it is closer, then I will update the closeness value and insert this new state into the Queue for future processing.
This process terminates when either the queue becomes empty or a state is discovered which is same as the target state.
The above approach takes approximately 1-3 seconds for cases where a minimum of 7 moves are required. I would be grateful if you can tell me how I can further optimize this solution.
The expected time according to the problem is 0.896s.

Resources