Microsoft Interview Question for Software Engineer in Tests






Comment hidden because of low score. Click to expand.
0
of 0 vote

CLR without recursion, is it right?

- zombie August 20, 2011 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 vote

Predecessor - (node->left)'s->rightmost node.....

Successor - (node->right)'s ->leftmost node.....

If they exist.....:)

- Anonymous August 20, 2011 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 votes

1. there are other situations
for instance, A simple tree below
A
B C
D
the predecessor of D node is A node, and the successor of D node is C

- Anonymous August 21, 2011 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 vote

I thin we can directly take the left most are the right most.

According to me

following should be the algorithms for inorder successor and predecessor

predecessor(t)
{
if (left[t]!=NULL)
return the leftmost element in left[t];
if parent[t]-right==t
return parent(t)
else return parent(parent(t))

}

for successor

successor[t]
if right[t]!=NULL
return leftmost element in right[t]

if (t==parent(t)->right)
return parent(parent(t));
else return parent(t)

- maverick! August 22, 2011 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 vote

I don't think the previous solution works. For predecessor(t), node t could still be less than the parent's parent (and I think there was a typo: you want the right-most element of t-> left)

The problem does not describe how the BTree handles equal values (are they inked on the same node? Are they left? Are they right?) and how to consider them if they do exist (are they predecessors? Successors? Neither?)

Assuming that equal nodes, if they exist, are considered neither successors nor predecessors, I suggest:

Predecessor(t) {
    if (!t)
       return null or throw exception;
    iterator i;
    if t->left {
        i = t->left;
        while (i->left and i == t) // skip any equal nodes if applicable
            i = i->left;
        while i->right   // find the rightmost element of t->left
            i = i->right;
        return i;
    }
    i = t;
    while (i->parent)
        i = i->parent;
        if i < t  // find the first ancestor that is less than t.  
                  // ie. an ancestor who's child within t's branch is to the right
            return i;
    }
    return null or throw exception; // No predecessor
        
}

For successor, just flip right/left and </>

- Anonymous August 22, 2011 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 votes

Oops, I forgot. When searching the ancestors, you have to loop i through any ancestors that are equal.

- Anonymous August 22, 2011 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 votes

Double oops. Ignore my eft comment. I forgot that I was simply comparing values when searching ancestors; I was not checking left/right branches.

- Anonymous August 22, 2011 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 votes

AAArrrgghh!! Triple oops. equal nodes are not necessarily consecutive. We need the rightmost node of t-> that
does not equal the value at t!

Okay, since recursion is not allowed, we need a loop when looking for the rightmost node of t->left. If that rightmost node has a value equal to t, then we start the algorithm again from that equal node.

Predecessor(t) {
    if (!t)
       return null or throw exception;
    iterator i = t;
    while (i.val() == t.val())  {
        if i->left {
            i = i->left;
            while i->right   // find the rightmost element of i->left
                i = i->right;
            if (i.val() != t.val())
                return i;
        }
    }
    // i either equals t, or is at a lower node that equals t
    while (i->parent) {
        i = i->parent;
        if i.val() < t.val()  // find the first ancestor that is less than t.
                    // ie. an ancestor who's child within the branch is to the right
            return i;
    }
    return null or throw exception; // No predecessor
}

Note: this will work even if equal nodes are placed to the right. In that case, the loops that check for equality will never be true.

again, for successor, just flip left/right and </>

- Anonymous August 22, 2011 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 votes

*sigh* and, of course, I need to avoid infinite oops:

Predecessor(t) {
    if (!t)
       return null or throw exception;
    iterator i = t;
    while (i.val() == t.val() and i->left)  {
        if i->left {
            i = i->left;
            while i->right   // find the rightmost element of i->left
                i = i->right;
            if (i.val() != t.val())
                return i;
        }
    }
    // i either equals t, or is at a lower node that equals t
    while (i->parent) {
        i = i->parent;
        if i.val() < t.val()  // find the first ancestor that is less than t.
                    // ie. an ancestor who's child within the branch is to the right
            return i;
    }
    return null or throw exception; // No predecessor
}

- Anonymous August 22, 2011 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 vote

#include <stdio.h>
#include <stdlib.h>

struct node 
{
	int data;
	struct node *left;
	struct node *right;
};

struct node *newNode(int data)
{
	struct node *node = (struct node*)malloc(sizeof(struct node));
	node->data = data;
	node->left = NULL;
	node->right = NULL;
	return node;
}

void insert(struct node *&node, int data)
{
	if(node == NULL)
	{
		node = newNode(data);
		return;
	}
	else
	{
		if(data > node->data)
		{
			insert(node->right, data);
		}
		else if(data <= node->data)
		{
			insert(node->left, data);
		}
	}

}

void Inorder(struct node *root)
{
	if(root != NULL)
	{
		Inorder(root->left);
		printf("%d ", root->data);
		Inorder(root->right);
	}
}

node *minimum(node *p)
{
	if(p == NULL)
		return NULL;
	while(p->left != NULL)
		p = p->left;
	return p;
}

node* maximum(node *p)
{
	if(p == NULL)
		return NULL;
	while(p->right != NULL)
		p = p->right;
	return p;
}

node *Successor(node *root, node *p)
{
	if(root == NULL || p == NULL)
		return NULL;
	if(p->right != NULL)
		return minimum(p->right);
	node *q = root;
	node *parent = q;
	if(q == p)
		return NULL;
	while(q != NULL)
	{
		parent = q;
		if((q->data < p->data) && (q != p))
			q = q->right;
		else
			break;
	}
	if(q == NULL || q != p)
		return NULL; 
	return parent;
}

node *Predecessor(node *root, node *p)
{
	if(NULL == p || NULL == root)
		return NULL;
	if(p->left != NULL)
	{
		return maximum(p->left);
	}
	node *q = root;
	node *parent = q;
	if(q == p)
		return NULL;
	while(q != NULL)
	{
		parent = q;
		if(q->data >= p->data && (q != p))
			q = q->left;
		else
			break;
	}
	if(q == NULL || q != p)
		return NULL;
	return parent;
}

node *findnode(node *root, int key)
{
	if(NULL == root)
		return NULL;
	node *p = root;
	while(p != NULL && key != p->data)
	{
		if(key <= p->data)
			p = p->left;
		else
			p = p->right;
	}

	return p;
}

- nim September 07, 2011 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 votes

Hey @Nim,

node *Predecessor(node *root, node *p)
{
	if(NULL == p || NULL == root)
		return NULL;
	if(p->left != NULL)
	{
		return maximum(p->left);
	}
	node *q = root;
	node *parent = q;
	if(q == p)
		return NULL;
	while(q != NULL)
	{
		parent = q;
		if(q->data >= p->data && (q != p))
			q = q->left;
		else
			break;
	}
	if(q == NULL || q != p)
		return NULL;
	return parent;
}

inside above function, I think the if condition is not applied correctly,

instead of

if((q->data < p->data) && (q != p))

the operator should be reversed

if((q->data > p->data) && (q != p))

The same goes with predecessor logic.

- Bhupesh Pant August 08, 2017 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 vote

<pre lang="" line="1" title="CodeMonkey32133" class="run-this">static void Successor(Node head, int num)
{
Node temp1=head, temp2=head;
int flag=3;

if(head==null)
{
return;
}

while(temp1.data!=num)
{
if(num<temp1.data)
{
temp2=temp1;
temp1=temp1.left;
flag=0;
}
else
{
temp2=temp1;
temp1=temp1.right;
flag=1;
}
}

if(temp1.right!=null)
{
temp1=temp1.right;

while(temp1.left!=null)
{
temp1=temp1.left;
}

System.out.println("INORDER successor of " + num + " is " + temp1.data);
}
else if (temp2.left == temp1)
{
System.out.println("INORDER successor of " + num + " is " + temp2.data);
flag=0;
}
else
{
Node temp3=head, temp4=head;

while(temp3.data!=num)
{
if(num<temp3.data)
{
temp4=temp3;
temp3=temp3.left;
flag=0;
}
else
{
temp3=temp3.right;
flag=1;
}
}

System.out.println("INORDER successor of " + num + " is " + temp4.data);

}

if(flag==3)
{
System.out.println("INORDER successor of " + num + " is undefined. ");

}

}</pre><pre title="CodeMonkey32133" input="yes">
</pre>

- Anonymous September 19, 2011 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 vote

FN(cn, d)
	if(cn->d == d)
		return cn
	prev = cn
	FN(cn->l)
	SN(cn->r)

Max(n)
	if(n->r == NULL)
		return n
	Max(n->r)

Min(n)
	if(n->l == NULL)
		return n
	Min(n->l)	

P(n)
	if(n->l)
		return Max(n->l)
	else if(n->d <= r->d)	
		return prev->data
	else
		return NULL

S(n)
	if(n->r)
		return Min(n->r)
	else if(n->d > r->d)
		return NULL
	else
		return prev->data

main
	n = FN(r, d)
	p = P(n)

- Prateek Caire September 23, 2011 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 vote

// InOrder Successor of a general Binary Tree. It can be even used for a BST . more optimisations // can be made for bst.
node * inOrderSuccessor(node *n)
{
// step 1 of the above algorithm
if( n->right != NULL )
return FindLeftMost(n->right);

// step 2 of the above algorithm
struct node *p = n->parent;
while(p != NULL && n == p->right)
{
n = p;
p = p->parent;
}
return p;
}

- Anonymous October 02, 2011 | Flag Reply
Comment hidden because of low score. Click to expand.
-1
of 1 vote

CLR should have this.

- Anonymous August 19, 2011 | Flag Reply


Add a Comment
Name:

Writing Code? Surround your code with {{{ and }}} to preserve whitespace.

Books

is a comprehensive book on getting a job at a top tech company, while focuses on dev interviews and does this for PMs.

Learn More

Videos

CareerCup's interview videos give you a real-life look at technical interviews. In these unscripted videos, watch how other candidates handle tough questions and how the interviewer thinks about their performance.

Learn More

Resume Review

Most engineers make critical mistakes on their resumes -- we can fix your resume with our custom resume review service. And, we use fellow engineers as our resume reviewers, so you can be sure that we "get" what you're saying.

Learn More

Mock Interviews

Our Mock Interviews will be conducted "in character" just like a real interview, and can focus on whatever topics you want. All our interviewers have worked for Microsoft, Google or Amazon, you know you'll get a true-to-life experience.

Learn More