data structure to store visited nodes in breadth first search - data-structures

I am applying bfs on a tree where each node have four stacks and one integer in it. I am storing them in a queue. I am using HashSet to store visited nodes. So before adding nodes in queue I am checking if HashSet contains that node or not. But the program is taking too much time to give output. Is my approach right or is there any other method to keep track of visited nodes ? Is Hashset good when we can not represent nodes in array ?
I am providing my code. Following is state class which represents one node.
static class State implements Serializable
{
int c=0;
Stack s[]=new Stack[4];
State()
{
for(int i=0;i<4;i++)
{
s[i]=new Stack();
}
}
}
My breadth first search algorithm is in following code
static int Bfs(HashSet<state>hs,state st,int n)
{
hs.add(st);
LinkedList<state> queue = new LinkedList<>();
queue.add(st);
while(!queue.isEmpty())
{
state sn=queue.remove();
if(sn.s[0].size()==n)
{
return sn.c;
}
for(int i=0;i<4;i++)
{
if(sn.s[i].size()>0)
{
int f=i;
for(int id:IntStream.range(0, 4).filter(x->(x!=f)).toArray())
{
state tm=(state)deepcopy(sn);
if((tm.s[id].size()==0)||((int)tm.s[id].peek()>(int)tm.s[i].peek()))
{
tm.s[id].push(tm.s[i].pop());
if(!hs.contains(tm))
{
tm.c+=1;
hs.add(tm);
queue.add(tm);
}
queue.add(tm);
}
}
}
}
}
return -1;
}
The above code is for problem "https://www.hackerrank.com/challenges/gena" which is just like tower of hanoi with 4 stacks. I need to put all disks in first stack. So in each deque operation I am popping last element from one stack and pushing it on other stacks one by one, and I am doing this popping operation on all stacks one by one.So for each state there will be 4x3 neighbours. For loop just stores index of all other stacks in variable id where popped element is to be pushed.

Yes I think is a really good way to store visited nodes especially because you cannot store any duplicates in Hashset. This is an alternative. I have coded.
Class Main {
public void bfs()
{
// BFS uses Queue data structure
Queue queue = new LinkedList();
queue.add(this.rootNode);
printNode(this.rootNode);
rootNode.visited = true;
while(!queue.isEmpty()) {
Node node = (Node)queue.remove();
Node child=null;
while((child=getUnvisitedChildNode(node))!=null) {
child.visited=true;
printNode(child);
queue.add(child);
}
}
// Clear visited property of nodes
clearNodes();
}

Related

Trace A Tree For the Recursion

I am feeling difficulty in tracing the tree for the following code ,can anyone please help me out ?
I need to see only recursion tree for the function .
private void helper(List<String> allIpAdreess, String s, int buildPointer, int[] path, int segment) {
if(buildPointer==s.length()&&segment==4) allIpAdreess.add(path[0]+"."+path[1]+"."+path[3]+"."+path[4]);
else if(buildPointer==s.length()||segment==4) {
return;
}
for(int len=1;len<=3&&len+buildPointer<s.length();len++) {
String takeSnapshot=s.substring(buildPointer, buildPointer+len);
helper(allIpAdreess,s,buildPointer+len,path,segment+1);
}
}
want to see the recursion tree for the i/p s=2551511135
helper(allIpAdreess,s,0,path,0);

Binary Search Tree Insertion using a void function

I have written two different codes for inserting into a binary tree, one works whereas other doesn't.
This is how my node looks:
struct node
{
int data;
node *left;
node *right;
};
The following is the code for node* newnode(int a)
node* newnode(int a)
{
node *temp=new node;
temp->data=a;
temp->left=nullptr;
temp->right=nullptr;
return temp;
}
And following are the two different codes for insertion:
This one returns a pointer to the node:
node* insertion(node *root, int a)
{
if(root==nullptr)
return newnode(a);
else if(a<root->data)
root->left=insertion(root->left, a);
else
root->right=insertion(root->right, a);
}
This one returns void:
void insertion2(node *root,int a)
{
if(root==nullptr)
root=newnode(a);
else if(a<root->data)
insertion2(root->left,a);
else
insertion2(root->right,a);
}
The one which returns void doesn't work. And as per the analysis I made, after the function call, root is still nullptr. Can anyone explain me why does it not work?
Notice that in the insertionversion you have root->left = insertion(root->left, a) and root->right = insertion(root->right, a), but you have nothing to the same effect in insertion2. In effect, insertion2 does nothing except leak memory.
To answer your question.
The problem with your insertion2 function is that the root variable will point to nullptr(NULL) at the called place and a new memory is allocated and pointed to a local reference inside insertion2() function. The reference change to a new memory location will not have any impact on the reference # calling place. As pointed by others, this call will always leak memory in #clearer answer.
To make this function to work. Move the object creation part # calling place and leave just the insert to this function.
something like the below should work.
void insertion2(node *root, node *new_node)
{
if(root==nullptr)
root=new_node;
else if(a<root->data)
insertion2(root->left,new_node);
else
insertion2(root->right,new_node);
}
// Create the new node and call the insert function
new_node = newnode(a);
insertion2(root, new_node);
Hope it clarifies your doubt!
in 2nd function root is always a local variable so updating it doesn't change main root variable, since the pointer itself is not passed by reference. You can achieve this by using call by reference, just change your
function heading as follows: void insertion2(node *&root,int a).
This way is working fine while using void return type. Declare a global variable, first.. it is set to one if the node to be inserted is first.. later change it to 0.
void insertRoot(struct node* newnode){
root=newnode;
}
void insert(struct node* root, int data)
{
if(first==1){
insertRoot(createNode(data));
first=0;
}else{
if (data < root->data){
if(root->left==NULL){
root->left=createNode(data);
}else{
insert(root->left,data);
}
}
else if (data > root->data){
if(root->right==NULL){
root->right=createNode(data);
}else{
insert(root->right,data);
}
}
}
}
The Root pointer from the calling method needs to be updated as well. So, you'll have to call the Insert2 method using something similar: Insert2(&BSTNodePtr, a). When you pass the address of the variable BSTNodePtr, the Insert2 method can update it's content.
Try this instead:
void Insert2(BSTNode **root, int a){
if (*root==NULL){
*root = new BSTNode(a);
}
else if (a<= (*root)->data){
Insert2(&((*root)->left), a);
}
else{
Insert2(&((*root)->right), a);
}
}

Building Red-Black Tree from sorted array in linear time

i know how to build it with n insertions ( each with O(log(n)) efficiency )
(n*log(n)) overall
,i also know that the equivalent structure of 2-3-4 tree can also be build with linear time from sorted array.
can anyone please provide a simple explanation about the red-black version?
No matter what kind of BST you are going to build. The algorithm will be the same. Only need to build balanced binary tree.
Place middle element to the current position
Place [begin; middle) elements to the left subtree.
Place (middle; end) elements to the right subtree.
This is O(N) algorithm. It can be shown, that the result tree will be balanced.
We have balanced tree, so by definition:
length(longest path) - length(shortest path) <= 1
So you need to mark all nodes as black, except the deepest nodes in the tree (mark them as red).
A complete binary tree of height H has 2^H-1 nodes.
To make a red black tree from a sorted list:
Remove every second item from the list until you have 2^H-1 items remaining for some H. Note that you will always have enough.
Build a complete tree out of the remaining items, all black.
Now attach all the items you removed to the tree. Each item will be a red node, attached to whichever of the black nodes around its proper position is a leaf.
The easiest way to do step (3) is just to do a pre-order traversal of the tree, attaching new red nodes to every black leaf until you run out of items.
NOTE: Sasha's algorithm also works, but this one obviously works.
From a functional data structure perspective: there is a paper for Constructing Red-Black Trees, which discovered the pattern of continuous insertion and related it to 1-2 number system.
It's a fun read.
For a working example implemented in Java, you may want to check out the method buildFromSorted(int level, int lo, int hi, int redLevel, ...) in Java.util.TreeMap.
One more comment about Java in particular: Unfortunately, if you have your own data structured in a sorted manner (e.g. as sorted ArrayLists), it is not so easy to get it into a TreeMap in a linear manner. One possibility however is to create your own implementation of a SortedMap or NavigableMap which is backed up by an ArrayList internally. Then it is possible to use this constructor to efficiently construct the TreeMap:
MySortedMap myMap = new MySortedMap(keyArray, valueArray);
new TreeMap<K, V> (myMap)
Here is some sample code for doing so:
public class MySortedMap<K,V> extends AbstractMap<K,V> implements NavigableMap<K,V> {
private ArrayList<K> keyArray;
private ArrayList<V> valueArray;
public Set<Map.Entry<K,V>> entrySet() {
return new EntrySet();
}
class EntryIterator implements Iterator<Map.Entry<K,V>> {
int i;
public EntryIterator () {
i = 0;
}
#Override
public boolean hasNext() {
if (i < keyArray.size()) {
return true;
} else {
return false;
}
}
#Override
public Map.Entry<K,V> next() {
if (hasNext()) {
Map.Entry<K,V> en = new Entry<K,V> (keyArray.get(i), valueArray.get(i));
i++;
return en;
} else {
return null;
}
}
}
final class Entry<K,V> implements Map.Entry<K,V> {
K key;
V value;
#Override
public K getKey() {
return key;
}
#Override
public V getValue() {
return value;
}
#Override
public V setValue(V value) {
this.value = value;
return value;
}
public Entry(K key, V value) {
this.key = key;
this.value = value;
}
}
class EntrySet extends AbstractSet<Map.Entry<K,V>> {
public Iterator<Map.Entry<K,V>> iterator() {
return new EntryIterator();
}
public int size() {
return keyArray.size();
}
}
public MySortedMap (ArrayList<K> keyArray, ArrayList<V> valueArray) {
if (keyArray.size() != valueArray.size()) {
throw new RuntimeException("Key and value arrays must have the same length!");
}
this.keyArray = keyArray;
this.valueArray = valueArray;
}
... some unused methods ...
}

parent of a node in a binary tree by searching given key

this is the function in c that's not giving me the solution
struct node* serch(struct node *ptr,int x)
{
if(ptr->data==x)
{
printf(" root of tree itself ");
}
else
{
struct node *ptr1,*ptr2;
ptr1=ptr->left;
ptr2=ptr->right;
while((ptr1->data!=x)&&(ptr2->data!=x))
{
if(ptr->data>x)
{
ptr=ptr1;
ptr1=ptr->left;
ptr2=ptr->right;
}
else if(ptr->data<x)
{
ptr=ptr2;
ptr1=ptr->left;
ptr2=ptr->right;
}
}
return ptr;
}
}
THE code works fine for the node's having both the children(particularly works fine upto the level the tree is balanced) but after that it doesn't work and gives the error
parentnode.exe has stopped working ,windows is checking for a solution.
You have several bugs
you are not returning something for the case ptr->data==x. Your c compiler should have given a warning that not all paths return a value.
you are not checking for nulls

How to implement a deque using two stacks

Deque ("doubled-ended queue") operations, en-queue and de-queue are possible from both ends.
How do to I define ADT operations for deque using 2 stacks?
The implementation should also take performance into consideration.
the simplest solution would be to use one stack as the head of the queue, and one as the tail.
The enqueue operations would just be a push to the respective stack, and the dequeue operations would just be a pop on the respective stack.
However, if the stack you want to dequeue from is empty, you'd have to pop each element from the other stack and push it back to the stack you want to dequeue from, and then dequeue the last one. That's not really good performance, so the overall performance of this implementation strongly depends on the workload. If your workload is a balanced number of front/back enqueue and dequeue operations, then this will be really really fast. But if your workload consists of a lot of alternating head-dequeues and tail-dequeues while the queue is large, then this will obviously be a bad approach.
Hope this helps
This is how I did it,
what really matters is that you make sure when you keep poping from one and it gets empty then it starts to pop from the other one, ( we got to make sure it pop from the end of stack ) we can do this by emptying one stack into the another. and keep poping there.
public class NewDeque {
Stack<E> frontstack;
Stack<E> endstack;
public NewDeque() {
frontstack = new Stack<>();
endstack = new Stack<>();
}
void addFirst(E e) {
frontstack.push(e);
}
E delFirst() {
if (frontstack.isEmpty()) {
while (!endstack.isEmpty()) {
frontstack.push(endstack.pop());
}
return frontstack.pop();
}
return frontstack.pop();
}
void addLast(E e) {
endstack.push(e);
}
E delLast() {
if (endstack.isEmpty()) {
while (!frontstack.isEmpty()) {
endstack.push(frontstack.pop());
}
return endstack.pop();
}
return endstack.pop();
}
int size() {
return frontstack.size() + endstack.size();
}
boolean isEmpty() {
return (size() == 0) ? true : false;
}
E get(int i) {
if (i < endstack.size()) {
return endstack.get(endstack.size() - i - 1);
} else {
return frontstack.get(i - endstack.size());
}
}
static void print(NewDeque<Integer> ds) {
for (int i = 0; i < ds.size(); i++) {
System.out.print(" " + ds.get(i) + " ");
}
}
an interesting way to do this is as follows
enqueue(q, x)
1) Push element x to stack1. This very simple, the problem is dequeue
dequeue(q)
1) If stacks1 and stack2 are empty then error "UNDERFLOW"
2) If stack2 is empty, then
while (stack1 is not empty) do
push all element from satck1 to stack2.
end while;
3) Pop the element from stack2 and return it.

Resources