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
Related
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();
}
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);
}
}
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 ...
}
I want to implement a insertion method for a Binary search tree, and come up with a solution below. I know there are plenty of code examples but I wonder what is the problem in my implementation? Or is there a problem? When I had traced it I thought I have missed something.
public void insertBST(Node<Double> head, int value){
if (head == null){
head = new Node<Double>(value);
return;
}
else {
if (head.getValue() > value)
insertBST(head.getLeft(), value);
else
insertBST(head.getRight(), value);
}
}
When you reassign a passed parameter, you're only changing the local variable, not the value passed to the function. You can read this question for more information - Is Java "pass-by-reference"? This is Java, right? Either way, a similar argument likely applies.
This is the problem with this line of code:
head = new Node<Double>(value);
You aren't changing the value passed into the function, so you never add to the tree.
You have two alternatives here, either the option presented by amdorra, or returning the current node:
public void insertBST(Node<Double> current, int value)
{
if (current == null)
{
return new Node<Double>(value);
}
else
{
if (head.getValue() > value)
head.setLeft(insertBST(head.getLeft(),value));
else
head.setRight(insertBST(head.getRight(),value));
return current;
}
}
To call the function, you can simply say:
root = insertBST(root, value);
With alternatives, the root will have to be handled as a special case.
at the beginning of you function you are adding the new Node to a part you will never have access to outside this function
so i will assume that your Node class looks like the following
Class Node{
private Node left;
private Node right;
//constructor, setters and getters and stuff
}
you could modify your code to look like the following:
if (head.getValue() > value){
if(head.getLeft == null) {
head.setLeft(new Node<Double>(value));
return;
}
insertBST(head.getLeft(),value);
}
else{
if(head.getRight == null) {
head.setRight(new Node<Double>(value));
return;
}
insertBST(head.getRight(),value);
}
you should also remove this part if (head==null) and always make sure you are sending a valid Node to the first call
I have a radTreeListView with multiple parent nodes,which can contain multiple child nodes which can also contain multiple sub-child nodes.
I want to make sure only 8 items are selected and no more than that. Those 8 selections MUST also be under the same parent node.
You could try something like that:
private RadTreeNode GetParentNode(RadTreeNode currentNode) {
if (currentNode.Parent!=null) {
return GetParentNode(currentNode.Parent);
}
return currentNode;
}
private void CountSelectedNodes(RadTreeNode firstNode, ref int selectedCount) {
if (firstNode.Nodes!=null) {
foreach(RadTreeNode node in firstNode.Nodes) {
CountSelectedNodes(node, ref selectedCount);
}
if (firstNode.IsSelected) {
selectedCount+=1;
}
}
}
private bool SelectionAllowed(RadTreeNode currentNode) {
RadTreeNode treeNode=GetParentNode(currentNode);
int selectedCount;
CountSelectedNodes(treeNode, ref selectedCount);
return selectedCount<=8;
}
(this code is not tested so there could be some bugs)
Call selectionAllowed() with the Node currently clicked