Sum of depth of all nodes in binary tree (Path length) - binary-tree

I am trying to implement a function to calculate path length of a binary tree and i am not able to get the correct answer. Can you check what i am doing wrong? Here is my code below:
public int pathLength() {
int sum = 0;
int c = 1;
pathLength(root, sum);
return sum;
}
public int pathLength(Node n, int sum) {
if(n.isRoot())
sum+= 0;
if(n.left == null && n.right == null)
return;
c++;
if(n.left != null)
sum += c;
if (n.right != null)
sum+=c;
pathLength(n.left, sum);
pathLength(n.right, sum);
}

There are a lot of things wrong with this code. It wouldn't even compile because a) In the 2nd function c is never declared (it is local in the first) and b) the 2nd function never returns a value.
But the biggest issue is the way you declare the 2nd function. "sum" is passed by value. That basically means a new copy of "sum" is created each time you call the function and is discarded when the function ends.
What you want to do is pass by reference. When doing this, the actual sum variable, not a copy, is passed to the function. So your code might look like this:
public void pathLength(Node n, int& sum) {
//if(n.isRoot()) <- not sure what this is for
// sum+= 0;
sum += 1; // Increment for this node
//if(n.left == null && n.right == null)
// return; // This conditional is not needed with next 2 if statements
//c++; <- Don't know what c is for
// Recursively call for child nodes
if(n.left != null)
pathLength(n.left, sum);
if (n.right != null)
pathLength(n.right, sum);
}
Note that this counts all the nodes in the tree. I assume that's what you want. If you want to find the deepest node, that's different.

Is it because of you set the initial value of c as 1 instead of 0?
The children of root should be at level 2 with the depth 1.

Here is an easy approach
Time : O(n) while the space will be O(h) where h is the height of the binary tree:
int sum(BinaryTree *node, int count){
if(node == nullptr){
return 0;
}
return count + sum(node->left, count+1)+sum(node->right, count+1);
}
int nodeDepths(BinaryTree *root) {
int count=0;
int ans=0;
ans =sum(root, count);
return ans;
}

Related

Partition sort for doubly linked list

Code translated to C from Wirth's book is following
void quicksort(int *array, int left, int right)
{
int v=array[(left+right)/2];
int i,j,x;
i=left;
j=right;
do {
while (array[i]<v) i++;
while (array[j]>v) j--;
if (i<=j) {
x=array[i];
array[i]=array[j];
array[j]=x;
i++;
j--;
}
} while (i<=j);
if (j>left) quicksort(array, left, j);
if (i<right) quicksort(array, i, right);
}
but that uses arrays - my stab at doubly linked lists (node structure here ):
void partitonSort(node **head,node **tail)
{
node *v; // here I want to use first or last element as pivot
node *i,*j;
do
{
while(i->key < v->key) i = i->next;
while(j->key > v->key) j = j->prev;
if(/*what boolean expression should I use here*/)
{
/*Is it necessary to replace swap operation
with insert and delete operations and
how to do it */
i = i->next;
j = j->prev;
}
}
while(/*what boolean expression should I use here*/);
if(/*what boolean expression should I use here*/)
partitonSort(head,&j);
if(/*what boolean expression should I use here*/)
partitonSort(&i,tail);
}
I left questions in the code comments:
- Should I replace swap operation with insert and delete
 and how to do this
- What boolean expressions I should use
Here is my concise solution with detailed comments:
/* a node of the doubly linked list */
struct Node
{
int data;
struct Node *next;
struct Node *prev;
};
/* A utility function to swap two elements */
void swap ( int* a, int* b )
{ int t = *a; *a = *b; *b = t; }
// A utility function to find last node of linked list
struct Node *lastNode(Node *root)
{
while (root && root->next)
root = root->next;
return root;
}
/* Considers last element as pivot, places the pivot element at its
correct position in sorted array, and places all smaller (smaller than
pivot) to left of pivot and all greater elements to right of pivot */
Node* partition(Node *l, Node *h)
{
// set pivot as h element
int x = h->data;
// similar to i = l-1 for array implementation
Node *i = l->prev;
// Similar to "for (int j = l; j <= h- 1; j++)"
for (Node *j = l; j != h; j = j->next)
{
if (j->data <= x)
{
// Similar to i++ for array
i = (i == NULL)? l : i->next;
swap(&(i->data), &(j->data));
}
}
i = (i == NULL)? l : i->next; // Similar to i++
swap(&(i->data), &(h->data));
return i;
}
/* A recursive implementation of quicksort for linked list */
void _quickSort(struct Node* l, struct Node *h)
{
if (h != NULL && l != h && l != h->next)
{
struct Node *p = partition(l, h);
_quickSort(l, p->prev);
_quickSort(p->next, h);
}
}
// The main function to sort a linked list. It mainly calls _quickSort()
void quickSort(struct Node *head)
{
// Find last node
struct Node *h = lastNode(head);
// Call the recursive QuickSort
_quickSort(head, h);
}
Yes but I prefer to change links instead of data
Here is pseudocode
PartitionSort(L)
if head[L] != tail[L] then
//Choose the pivot node, first node or last node is the option
pivot := tail[L]
//Partition step, we distribute nodes of the linked list into three sublists
curr := head
while curr != NULL do
if key[curr] < key[pivot] then
pushBack(curr,Less)
else if key[curr] = key[pivot] then
pushBack(curr,Equal)
else
pushBack(curr,Greater)
end if
end if
curr := next[curr]
end while
// Here me make sure that we partitioned linked list correctly
// We should set next of tail pointers and prev of head pointers to NULL
//Now we do recursive calls on sublists with keys not equal to the pivot key
PartitionSort(Less)
PartitionSort(Greater)
// Now we concatenate sublists
if tail[Less] != NULL then
next[tail[Less]] := head[Equal]
else
head[Less] := head[Equal]
end if
if head[Equal] then
prev[head[Equal]] = tail[Less]
tail[Less] = tail[Equal]
end if
if tail[Less] != NULL then
next[tail[Less]] := head[Greater]
else
head[Less] := head[Greater]
end if
if head[Greater] then
prev[head[Greater]] = tail[Less]
tail[Less] = tail[Greater]
end if
L := Less
end if

Using Instance Variables vs Function Arguments in Recursion

Is there any difference, efficiency-wise, in using instance variables vs passing arguments by function calls during recursion? For example, I was recently doing a problem on Leetcode which asked to:
Given a Binary Search Tree (BST), convert it to a Greater Tree such that every key of the original BST is changed to the original key plus sum of all keys greater than the original key in BST.
My solution and the most popular one by far is as follows: 46 ms according to Leetcode
class Solution {
public:
int sum = 0;
TreeNode* convertBST(TreeNode* root) {
if (root == NULL) return 0;
convertBST(root->right);
sum += root->val;
root->val = sum;
convertBST(root->left);
return root;
}
};
But why couldn't we also use the following solution, or does it matter? 59 ms runtime according to Leetcode
class Solution {
public:
TreeNode* convertBST(TreeNode* root, int* sum) {
if (root == NULL) return NULL;
convertBST(root->right, sum);
*sum += root->val;
root->val = *sum;
convertBST(root->left, sum);
return root;
}
TreeNode* convertBST(TreeNode* root) {
int sum = 0;
return convertBST(root, & sum);
}
};
Thanks

Can insertion sort be post order?

public class insSort {
int i,j,key; //j=1
public void rec(int a[],int pos){
if(pos>a.length-1){
return;
}
key= a[pos];
i=pos-1;
while((i>=0)&&(a[i]>key)){//swapping
a[i+1]=a[i];
i--;
a[i+1]=key;
}
pos++;
rec(a,pos);//post order
}
can it be considered as insertion sort? or should it be in-order?
Is it a universal practice to use in-order for recursive algorithms?if so why is it so?
The example code in the question is a tail recursive version, which a compiler may optimize into a loop (no recursion). I converted the example code to C++ with some minor clean up. The initial call should be rec(1) (initial value of pos == 1).
class insSort
{
public:
int a[8];
void rec(int pos){
int i,value;
if(pos >= (sizeof(a)/sizeof(a[0])))
return;
value = a[pos]; // get value
i = pos-1;
while((i >= 0) && (a[i] > value)){ // shift up
a[i+1] = a[i];
i--;
}
a[i+1] = value; // insert value
pos++;
rec(pos);
}
};

Reverse alternate elements and append to end of the list

Given a linked list as a->x->b->y->c->z , we need to reverse alternate element and append to end of list. That is , output it as a->b->c->z->y->x.
I have an O(n) solution but it takes extra memory , we take 2 lists and fill it with alternate elements respectively , so the two lists are a b c and x y z and then we will reverse the second list and append it to the tail of first so that it becomes a b c z y x .
My question is can we do it in place ? Or is there any other algorithm for the same ?
The basic idea:
Store x.
Make a point to b.
Make y point to the stored element (x).
Make b point to c.
etc.
At the end, make the last element at an odd position point to the stored element.
Pseudo-code: (simplified end-of-list check for readability)
current = startOfList
stored = NULL
while !endOfList
temp = current.next
current.next = current.next.next
temp.next = stored
stored = temp
current = current.next
current.next = stored
Complexity:
O(n) time, O(1) space.
Here is logic in recursion mode
public static Node alRev(Node head)
{
if (head == null) return head;
if (head.next != null)
{
if (head.next.next != null)
{
Node n = head.next;
head.next = head.next.next;
n.next = null;
Node temp = alRev(head.next);
if (temp != null){
temp.next = n;
return n;
}
}
else
return head.next;
}
else
return head;
return null;
}
This is a recent question from amazon interview, the Idea looks good and there seems to be no trick in it.
Java code with comments:
static void change(Node n)
{
if(n == null)
return;
Node current = n;
Node next = null, prev = null;
while(current != null && current.next != null)
{
// One of the alternate node which is to be reversed.
Node temp = current.next;
current.next = temp.next;
// Reverse the alternate node by changing its next pointer.
temp.next = next;
next = temp;
// This node will be used in the final step
// outside the loop to attach reversed nodes.
prev = current;
current = current.next;
}
// If there are odd number of nodes in the linked list.
if(current != null)
prev = current;
// Attach the reversed list to the unreversed list.
prev.next = next;
}
here the c code which don't uses any extra space for doing this..enjoy and have fun
in case of any doubt feel free to ask
#include<stdio.h>
#include<stdlib.h>
int n;
struct link
{
int val;
struct link *next;
};
void show(struct link *);
void addatbeg(struct link **p,int num)
{
struct link *temp,*help;
help=*p;
temp=(struct link *)malloc(sizeof(struct link));
temp->val=num;
temp->next=NULL;
if(help==NULL)
{
*p=temp;
}
else
{
temp->next=help;
*p=temp;
}
n++;
show(*p);
}
void revapp(struct link **p)
{
struct link *temp,*help,*q,*r;
r=NULL;
temp=*p;
help=*p;
while(temp->next!=NULL)
{
temp=temp->next;
q=r; //this portion will revrse the even position numbers
r=temp;
temp=temp->next;
//for making a connection between odd place numbers
if(help->next->next!=NULL)
{
help->next=temp;
help=help->next;
r->next=q;
}
else
{
r->next=q;
help->next=r;
show(*p);
return;
}
}
}
void show(struct link *q)
{
struct link *temp=q;
printf("\t");
while(q!=NULL )
{
printf("%d ->",q->val);
q=q->next;
if(q==temp)
{
printf("NULL\n");
return;
}
}
printf("NULL\n");
}
int main()
{
n=0;
struct link *p;
p=NULL;
// you can take user defined input but here i am solving it on predefined list
addatbeg(&p,8);
addatbeg(&p,7);
addatbeg(&p,6);
addatbeg(&p,5);
addatbeg(&p,4);
addatbeg(&p,3);
addatbeg(&p,2);
addatbeg(&p,1);
revapp(&p);
return 0;
}`

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.

Resources