why is static keyword required for finding if a given binary tree is BST or not? - data-structures

Here is the code for finding if the given binary tree was a binary search tree(BST) or not:
bool isBST(struct node* root)
{
// traverse the tree in inorder fashion and keep track of prev node
if (root)
{
struct node *prev = NULL;
if (!isBST(root->left))
return false;
// Allows only distinct valued nodes
if (prev != NULL && root->data <= prev->data)
return false;
prev = root;
return isBST(root->right);
}
return true;
}
However this does not give the correct output.
when I changed my code to the below version it worked fine:
bool isbst(node * root)
{
static struct node * prev = NULL;
if( root)
{
if(!isbst(root->left))
return false;
if(prev != NULL && root->data < prev->data)
return false;
prev = root;
return isbst(root-> right);
}
return true;
}
My question is why does it work when the line static struct node * prev = NULL; was added to the code?
In my previous code even though the variable 'prev' was declared again and again it was update to the root each time..my code should have worked fine. But it didn't. what is wrong with it?

static struct node * prev = NULL;
In the above line, the use of the static keyword gives rise to two things:
1) prev is only initialised to null exactly once, i.e. the first time it is reached
2) More importantly, because prev is static, any update to its value is retained in subsequent calls to the function isBST.
In your initial/bad/non-working case without the static keyword
struct node *prev = NULL;
1) You are not retaining the value of the previous node (this is precisely why your algo didn't work)
2) Not only that you are setting it to null
In short, with the use of static, you are retaining the previous node's value (your intention). In the other case, you aren't retaining the previous node's value
static initialisation of a variable within a function scope in C++ is a neat way to retain values between recursive calls.

Related

Find kth min node in AVL tree

I now have built a AVL tree, Here is a function to find kth min node in AVL tree
(k started from 0)
Code:
int kthMin(int k)
{
int input=k+1;
int count=0;
return KthElement(root,count,input);
}
int KthElement( IAVLTreeNode * root, int count, int k)
{
if( root)
{
KthElement(root->getLeft(), count,k);
count ++;
if( count == k)
return root->getKey();
KthElement(root->getRight(),count,k);
}
return NULL;
}
It can find some of right nodes, but some may fail, anyone can help me debug this>
THanks
From the root, after recursing left, count will be 1, regardless of how many nodes are on the left.
You need to change count in the recursive calls, so change count to be passed by reference (assuming this is C++).
int KthElement( IAVLTreeNode * root, int &count, int k)
(I don't think any other code changes are required to get pass by reference to work here).
And beyond that you need to actually return the value generated in the recursive call, i.e. change:
KthElement(root->getLeft(), count, k);
to:
int val = KthElement(root->getLeft(), count, k);
if (val != 0)
return val;
And similarly for getRight.
Note I used 0, not NULL. NULL is typically used to refer to a null pointer, and it converts to a 0 int (the latter is preferred when using int).
This of course assumes that 0 isn't a valid node in your tree (otherwise your code won't work). If it is, you'll need to find another value to use, or a pointer to the node instead (in which case you can use NULL to indicate not found).
Here is simple algorithm for Kth smallest node in any tree in general:-
count=0, found=false;
kthElement(Node p,int k) {
if(p==NULL)
return -1
else {
value = kthElement(p.left)
if(found)
return value
count++
if(count==k) {
found = true
return p.value
}
value = kthElement(p.right)
return value
}
}
Note:- Use of global variables is the key.

PreOrder Successor of a Node in BST

I'm trying this question for sometime but couldn't figure out the algorithm. My preference is to do it iteratively. Till now, I've figure out something but not sure on some point.
Currently, My algorithm looks like:
First traverse the tree to find the node
While traversing the tree, keep track of the previous node.
if you find the node, check if left child is present then that is successor return.
if left child is not present then check if right child is present the that is successor and return.
if the node(is left to the parent) and don't have left or right child then we've saved the prev node earlier then either prev or prev's right child is the successor.
But what if the node we found is in the right to parent and don't have left or right child how to find successor of this node?
May be there are many flaws in this algorithm as still I've not understand all the cases properly. If anyone has any idea or algorithm please share.
Thanks in advance.
when you find a node in preorder, to find its successor is just travesing to its next node.
what I was thinking first is the relationship of a node and its successor's values in pre-oder, but I found that it seems not very clear like the relationship in in-order. I think there is only one step beteen a node and its successor(if exists) : just move on travesing. So I design this algorithm.
my algorithm below is based on preorder travesal, it can run on a binary tree,not only BST.
#define NOT_FOUND -1
#define NEXT 0
#define FOUND 1
struct node {
struct node *p;//parent,but useless here
struct node *l;//left child
struct node *r;//right child
int value;
};
int travese(struct node* bnode, int* flag,int value)
{
if(bnode == NULL)
return 0;
else
{
if(*flag == FOUND)
//when the successor is found,do pruning.
return 1;
else if(*flag == NEXT) {
printf("successor:%d\n",bnode->value);
*flag = FOUND;
return 1;
}
else if(*flag == NOT_FOUND && bnode->value == value)
*flag = NEXT;
travese(bnode->l,flag,value);
travese(bnode->r,flag,value);
}
return 0;
}
and use it by:
int flag = NOT_FOUND;
travese(root,&flag,value);
if(flag == NEXT || flag == NOT_FOUND)
printf("no successor.\n");
EDIT:
turning a recurrence algorithm to a iterative one is not difficult by using a stack like below:
int preorder_travese_with_stack(struct node* bnode, int* flag,int value)
{
if(bnode == NULL)
return 0;
struct stack s;//some kind of implement
push(s,bnode);
while(NotEmpty(s) && *flag) {
struct node *curNode = pop(s);
if(*flag == NEXT) {
printf("successor:%d\n",curNode->value);
*flag = FOUND;
return 1;
}
else if(*flag == NOT_FOUND && curNode->value == value)
*flag = NEXT;
push(s,curNode->r);
push(s,curNode->l);
}
return 0;
}
but according to your comment and original description, I think the one you want is iterative algorithm without a stack.here it is.
After thinking ,searching and trying, I wrote one. When travse the tree iteratively without stack , the parent of a node is not useless any more. In a path, some nodes is visited not only once, and you need to record its direction at that time.
int preorder_travese_without_stack(struct node *root,int value,int *flag)
{
int state=1;
//state: traveral direction on a node
//1 for going down
//2 for going up from its left chlid
//3 for going up from its right child
struct node *cur = root;
while(1) {
if(state == 1) //first visit
{
//common travese:
//printf("%d ",cur->value);
if(cur->value == value && *flag == NOT_FOUND)
*flag = NEXT;
else if (*flag==NEXT) {
*flag = FOUND;
printf("successor:%d\n",cur->value);
break;
}
}
if((state == 1)&&(cur->l!=NULL))
cur = cur->l;
else if((state==1)&&(cur->l==NULL))
{
state = 2;
continue;
}
else if(state==2) {
if(cur->r != NULL ) {
cur=cur->r;
state = 1;
}
else
{
if(cur->p!=NULL)
{
if(cur==cur->p->r)
state = 3;
//else state keeps 2
cur=cur->p;
}
else //cur->p==NULL
{
if(cur->p->r!=NULL)
{
cur=cur->p->r;
state = 1;
}
else
break;
//end up in lchild of root
//because root's rchild is NULL
}
}
continue;
}
else //state ==3
{
if(cur->p!=NULL)
{
if(cur==cur->p->l)
state = 2;
else
state = 3;
cur=cur->p;
continue;
}
else
break;
}
}
}
the usage is the same as the first recurrence one.
If you are confused yet,mostly about the direction of a node , you can draw a tree and draw the path of pre-order traverse on paper,it would help.
I'm not sure there are bugs left in the code,but it works well on the tree below:
0
/ \
1 2
/ \ / \
3 4 5 6
btw,"wirte down pre-order (or else) travese algorithm of a tree both by recurrence and iteration" is a common interview problem, although solving the latter by a stack is permitted.but I think the BST requirement is unnecessary in pre-order travese.
My implementation of the algorithm does not use the key. Therefore it is possible to use it in any kind of binary tree, not only in Binary search trees.
The algorith I used is this:
if given node is not present, return NULL
if node has left child, return left child
if node has right child, return right child
return right child of the closest ancestor whose right child is present and not yet processed
Bellow there is my solution.
TreeNode<ItemType>* CBinaryTree<ItemType>::succesorPreOrder(TreeNode<ItemType> *wStartNode)
{
//if given node is not present, return NULL
if (wStartNode == NULL) return NULL;
/* if node has left child, return left child */
if (wStartNode->left != NULL) return wStartNode->left;
/* if node has right child, return right child */
if (wStartNode->right != NULL) return wStartNode->right;
/* if node isLeaf
return right child of the closest ancestor whose right child is present and not yet processed*/
if (isLeaf(wStartNode)) {
TreeNode<ItemType> *cur = wStartNode;
TreeNode<ItemType> *y = wStartNode->parent;
while (y->right == NULL && y->parent!=NULL){
cur = y;
y = y->parent;
}
while (y != NULL && cur == y->right) {
cur = y;
y = y->parent;
}
return y->right;
}
}
bool CBinaryTree<ItemType>::isLeaf(TreeNode<ItemType> *wStartNode){
if (wStartNode->left == NULL && wStartNode->right == NULL) return true;
else return false;
};

How To Find the Mirror Node of a Given Node (or item) in a Binary Tree Efficiently

I've been thinking of this problem, and I have not found a good, efficient solution.
How to find the mirror node of a given node (or item) in a binary tree?
// Node definition
struct _Node {
char data;
struct _Node* left;
struct _Node* right;
} Node;
// Assumption:
// "given" is guaranteed in the binary tree ("root" which is not NULL)
Node* FindMirrorNode(Node* root, Node* given)
{
// Implementation here
}
// OR:
// Assumption:
// in the binary tree ("root"), there is no repeated items, which mean in each node the char data is unique;
// The char "given" is guaranteed in the binary tree.
char FindMirrorNodeData(Node* root, char given)
{
// Implementation here
}
NOTE: I'm NOT asking on how to find a mirror tree of a given tree :-)
For example, considering the tree below
A
/ \
B C
/ / \
D E F
\ / \
G H I
The mirror node of 'D' is node 'F'; while the mirror node of 'G' is NULL.
Thanks.
I've written a solution for the function with the char. Is FindMirrorNode(r, n) == FindMirrorNodeData(r, n->data)?
You have to go through the entire tree searching for the given data while keeping the mirror nodes on the stack. That's a quite simple solution, still quite efficient.
If you want you may transform tail-calls into while.
static Node* FindMirrorNodeRec(char given, Node* left, Node* right)
{
// if either node is NULL then there is no mirror node
if (left == NULL || right == NULL)
return NULL;
// check the current candidates
if (given == left->data)
return right;
if (given == right->data)
return left;
// try recursively
// (first external then internal nodes)
Node* res = FindMirrorNodeRec(given, left->left, right->right);
if (res != NULL)
return res;
return FindMirrorNodeRec(given, left->right, right->left);
}
Node* FindMirrorNodeData(Node* root, char given)
{
if (root == NULL)
return NULL;
if (given == root->data)
return root;
// call the search function
return FindMirrorNodeRec(given, root->left, root->right);
}
Thanks for Chris's beautiful solution. It worked.
Node* FindMirrorNodeRec(Node* given, Node* left, Node* right)
{
// There is no mirror node if either node is NULL
if (!left || !right)
return NULL;
// Check the left and right
if (given == left)
return right;
if (given == right)
return left;
// Try recursively (first external and then internal)
Node* mir = FindMirrorNodeRec(given, left->left, right->right);
if (mir)
return mir;
// Internally
return FindMirrorNodeRec(given, left->right, right->left);
}
// Find the mirror node of the given node
// Assumption: root is not NULL, and the given node is guaranteed
// in the tree (of course, not NULL :-)
Node* FindMirrorNode(Node* const root, Node* const given)
{
if (!root || root == given)
return root;
return FindMirrorNodeRec(given, root->left, root->right);
}

How to count the number of right children in a binary tree?

How to count the number of right children in a binary tree?
This means that I only want the children marked as right.
Ex.
(Left | Right)
F(Root)
G | H
T U | I J
The right children would be U,H,and J.
What would be the algorithm to find these.
int count(Tree *r){
if(r == NULL) return 0;
int num_l=0, num_r=0;
if(r->left != NULL)
num_l = count(r->left);
if(r->right != NULL)
num_r = count(r->right)+1;
return num_l+num_r
}
In recursive approach,
You would be calling a function to traverse your tree,
for current node, you need to:
check if current node has right child (then increment the counter), and then call the function recursively for right node.
check if current node has left child, call the function recursively for left node.
This should work.
Do a simple traversal on the tree (i.e. post order, in order) and for each node do +1 if it has right child.
Example (didn't try to compile and check it):
int countRightChildren(Node root)
{
if (root == null) return 0;
int selfCount = (root.getRightChild() != null) ? 1 : 0;
return selfCount + countRightChildren(root.getLeftChild()) + countRightChildren(root.getRightChild());
}
You can do it recursively as:
If tree does not exist, there are no
R children.
If tree exists, then # R children = #
R children in R-subtree + # R
children in L-subtree
.
int countRChildren(Node *root) {
if(!root) // tree does not exist.
return 0;
// tree exists...now see if R node exits or not.
if(root->right) // right node exist
// return 1 + # of R children in L/R subtree.
return 1 + countRChildren(root->right) + countRChildren(root->left);
else // right nodes does not exist.
// total count of R children will come from left subtree.
return countRChildren(root->left);
}
This is include how i build the struct
struct Item
{
int info;
struct Item* right;
struct Item* left;
};
typedef struct Item* Node;
int countRightSons(Node tree)
{
if(!tree)
return 0;
if(tree->right != NULL)
return 1 + countRightSons(tree->right) + countRightSons(tree->left);
return countRightSons(tree->left);
}
Simple recursive approach,
check (even if not needed) for all the 4 possibilities:
left and right does not exists
left and right exists
left exists and right doesnt
right exists and left doesnt
public static int countRightChildren(BST tree) {
if (tree.root==null) return Integer.MIN_VALUE;
return countRightChildren(tree.root);}
public static int countRightChildren(Node curr) {
if (curr.right==null&&curr.left==null) return 0;
else if (curr.right!=null&&curr.left==null)
return curr.right.data+countRightChildren(curr.right);
else if (curr.right==null&&curr.left!=null)
return countRightChildren(curr.left);
else if (curr.right!=null&&curr.left!=null)
return curr.right.data+countRightChildren(curr.left)+countRightChildren(curr.right);
return Integer.MIN_VALUE;
}

searching a binary tree

I'm writing an iterative function to search a binary tree for a certain value. This is localized to signed ints until I get into how to genericize classes.
Assume that my class is BinarySearchTree, and it has a pointer to the root node of the tree. Also assume that nodes are inserted through an insert function, and have pointers to two children. Here is a much abbreviated version of the Node struct:
struct Node
{
public:
Node *left_, *right_;
int value_
Node(int val) : value_(val), left_(0), right_(0) { }
//done in this manner to always make sure blank children are
//init to zero, or null
Node(int val, Node *left, Node *right) : value_(val), left_(0), right_(0)
{ left_ = left; right_ = right; }
}
So, you can safely assume that a node's uninit pointers will be NULL.
Here is my code:
int BinarySearchTree::search(int val)
{
Node* next = this->root();
while (next->left() != 0 || next->right () != 0)
{
if (val == next->value())
{
return next->value();
}
else if (val < next->value())
{
next = next->left();
}
else if (val > next->value())
{
next = next->right();
}
}
//not found
return 0;
}
This code is being rejected by a friend for two reasons:
1) If next has no children, both will evaluate to zero and I will prematurely exit the loop (I will never check the searched val against next's value).
2) If next has one child, but the data you are searching for should be on the empty side of the tree, next will be set to 0, and it will loop again, comparing next (which is 0) to the left and right trees like while(0->left()), resulting in undefined behavior.
I am told that the solution to both problems lies in the loop condition, but I can't see what I can do to easily remedy the situation. Can the community of Stack Overflow offer any insights?
I think you should be testing if next is not NULL in your loop like so:
int BinarySearchTree::search(int val)
{
Node* next = this->root();
while (next)
{
if (val == next->value())
{
return next->value();
}
else if (val < next->value())
{
next = next->left();
}
else if (val > next->value())
{
next = next->right();
}
}
//not found
return 0;
}
Try this:
while (next != NULL) ?
First of all, I'm not sure why you are returning an int. What if you are searching for 0 in the tree. You probably want something like this:
bool BinarySearchTree::Search(int val) {
Node* current = root();
while (current != NULL) {
// Check if it's here
if (val == current->value()) {
return true;
}
if (val < current->value()) {
current = current->left();
} else {
current = current->right();
}
}
// Not found
return false;
}
Notice that the loop invariant: at the beginning of each loop, you are at a non null node that you need to "process". First check if it's the node you want. If not, make a branch, and let the loop decide if the branch was "good" (ie - non null). Then you'll let the next loop iteration take care of testing.

Resources