In flatten function I can't understand recursion parts??
2.when flatten return root(not the if section), how root received here?
//below is the code of flatten() which start from end of node .each node have two pointers next and down . This function merge and sort all of them and return them.for help attach full code in last.
// Java program for flattening a Linked List
Node flatten(Node root) {
// Base Cases
if (root == null || root.right == null)
return root;
// recur for list on right
root.right = flatten(root.right);
// now merge
root = merge(root, root.right);
// return the root
// it will be in turn merged with its left
return root;
}
//full code for help
//flatten inked list full code
// debug in vs studio
class LinkedList {
Node head; // head of list
/* Linked list Node */
class Node {
int data;
Node right, down;
Node(int data) {
this.data = data;
right = null;
down = null;
}
}
// An utility function to merge two sorted linked lists
Node merge(Node a, Node b) {
// if first linked list is empty then second
// is the answer
if (a == null)
return b;
// if second linked list is empty then first
// is the result
if (b == null)
return a;
// compare the data members of the two linked lists
// and put the larger one in the result
Node result;
if (a.data < b.data) {
result = a;
result.down = merge(a.down, b);
}
else {
result = b;
result.down = merge(a, b.down);
}
result.right = null;
return result;
}
Node flatten(Node root) {
// Base Cases
if (root == null || root.right == null)
return root;
// recur for list on right
root.right = flatten(root.right);
// now merge
root = merge(root, root.right);
// return the root
// it will be in turn merged with its left
return root;
}
/*
* Utility function to insert a node at beginning of the
* linked list
*/
Node push(Node head_ref, int data) {
/*
* 1 & 2: Allocate the Node &
* Put in the data
*/
Node new_node = new Node(data);
/* 3. Make next of new Node as head */
new_node.down = head_ref;
/* 4. Move the head to point to new Node */
head_ref = new_node;
/* 5. return to link it back */
return head_ref;
}
void printList() {
Node temp = head;
while (temp != null) {
System.out.print(temp.data + " ");
temp = temp.down;
}
System.out.println();
}
// Driver's code
public static void main(String args[]) {
LinkedList L = new LinkedList();
L.head = L.push(L.head, 7);
L.head = L.push(L.head, 5);
L.head.right = L.push(L.head.right, 50);
L.head.right = L.push(L.head.right, 22);
L.head.right = L.push(L.head.right, 19);
L.head.right.right = L.push(L.head.right.right, 45);
L.head.right.right = L.push(L.head.right.right, 40);
L.head.right.right = L.push(L.head.right.right, 35);
L.head.right.right = L.push(L.head.right.right, 20);
// Function call
L.head = L.flatten(L.head);
L.printList();
}
If I understand correctly, you want to know how the recursion works in this code.
1 Node flatten(Node root) {
2 // Base Cases
3 if (root == null || root.right == null)
4 return root;
5
6 // recur for list on right
7 root.right = flatten(root.right);
8
9 // now merge
10 root = merge(root, root.right);
11
12 // return the root
13 // it will be in turn merged with its left
14 return root;
15 }
Let's say our linked list looks like this:
5 -> 10 -> 19 -> 28
| | | |
V V V V
7 20 22 35
| | |
V V V
8 50 40
| |
V V
30 45
Now, let's traverse this method line by line.
The base case ensures that once we reach the right most linked list, it is returned as is.
So, now since we passed the above-linked list to this function whose root is not null and has another linked list to its right, function control moves to line 7.
On line 7, flatten(root.right) function is called. Let us assume for our sanity, that this function does exactly what it is supposed to and it flattens all the linked lists to its right and we assign this newly flattened right portion of the linked list to root.right.
Now, all we are left with is our base linked list 5-7-8-30 and to its right the flattened linked list. So, we only have to merge these 2 now and return it back which we do in line 10 and 14.
If you, noticed above, I have avoided the hassle of going into the trouble of following the rabbit hole of thinking about function calls on Line 7. This simplifies the recursive logic.
We can think recursively as well and reach to same conclusion because for each subsequent flatten function call, the merge will happen and the root will be returned to the previous function call which will be assigned to root.right in parent function and then merged and returned to its parent function call and the same process will be followed until the control reaches the head of the linked list where only 2 linked lists will remain at the end which will be merged and returned back.
There is a 3rd way to understand this visually with the help of a function callstack diagram. I'll update this answer later to include that when I get some time.
Related
Can I implement a binary heap by only using a TreeNode inferface (has children, or left/right, or/and parent.. something like this)?
I want to not rely on using array or linked list.
If I don't use array or linked list, I have a trouble inserting the next element in the correct place & keep it a complete binary tree (all non-leaf nodes are full). Also have trouble taking out the root and re-heapifying.
One key observation is this:
The path from the root to the last leaf in a complete binary tree is represented by the binary representation of the size of the tree (number of nodes in the tree).
For instance, this tree has 9 nodes.
1
/ \
4 2
/ \ / \
6 5 3 7
/ \
9 8
9 in binary is 1001. Skipping the most significant "1", this can be read from left-to-right as 0, 0, 1 or "left-left-right". That describes indeed the path from root to the leaf node with value 8!
The same principle holds for when you need to find the insertion point for a new node. Then first increase the size, so this becomes 10 in the example. The binary representation is 1010. Skipping the first digit, this represents "left-right-left". The last direction ("left") gives information about the edge that must be added. And indeed, "left-right" leads us to the node with value 5, and a new node has to be inserted as left-child of that node!
To restore the heap property after an insertion, keep track of the path towards the newly inserted leaf (for example, when coming back out of a recursive function), and wind that path back, each time verifying the heap property, and swapping values when necessary.
Similarly, for an extraction of the root value: first find the node to delete (see above), delete that node and assign the deleted value to the root node. Then sift down the heap to restore the heap property.
Here is an implementation in plain JavaScript -- it should be easy to port this to any other language:
class Node {
constructor(value) {
this.value = value;
this.left = this.right = null;
}
swapValueWith(other) { // We don't swap nodes, just their values
let temp = this.value;
this.value = other.value;
other.value = temp;
}
}
class HeapTree {
constructor() {
this.root = null;
this.size = 0;
}
insert(value) {
this.size++;
if (this.root == null) {
this.root = new Node(value);
} else { // Use the binary representation of the size to find insertion point
this.insertRecursive(this.root, 1 << (Math.floor(Math.log2(this.size)) - 1), value);
}
}
insertRecursive(node, bit, value) {
let side = this.size & bit;
let child;
if (side > 0) {
if (bit == 1) node.right = new Node(value);
child = node.right;
} else {
if (bit == 1) node.left = new Node(value);
child = node.left;
}
if (bit > 1) this.insertRecursive(child, bit>>1, value)
if (node.value > child.value) node.swapValueWith(child); // sift up
}
extract() {
if (this.root == null) return; // Nothing to extract
let value = this.root.value; // The value to return
if (this.size == 1) {
this.root = null;
} else {
// Use the binary representation of the size to find last leaf -- to be deleted
this.root.value = this.deleteRecursive(this.root, 1 << (Math.floor(Math.log2(this.size)) - 1));
// Sift down
let node = this.root;
while (true) {
let minNode = node;
if (node.left != null && node.left.value < minNode.value) minNode = node.left;
if (node.right != null && node.right.value < minNode.value) minNode = node.right;
if (minNode === node) break;
node.swapValueWith(minNode);
node = minNode;
}
}
this.size--;
return value;
}
deleteRecursive(node, bit) {
let side = this.size & bit;
let child;
if (side > 0) {
child = node.right;
if (bit == 1) node.right = null;
} else {
child = node.left;
if (bit == 1) node.left = null;
}
return bit == 1 ? child.value : this.deleteRecursive(child, bit>>1);
}
}
// Demo
let heap = new HeapTree();
for (let value of [4,2,5,8,7,9,0,3,1,6]){
heap.insert(value);
}
// Output the values in sorted order:
while (heap.root != null) {
console.log(heap.extract());
}
I am looking at this challenge:
Suppose two subtrees in a binary search tree have been swapped, and that the BST property is broken. Devise an algorithm that identifies the two swapped subtrees in O(n) time.
My Thoughts
When an inorder traversal of a BST is done, the elements are sorted.
Now when two subtrees are swapped, the inorder traversal will
not be sorted. So if you compare the inorder traversal of the original
tree and the swapped one, it would be like you have taken two subsets
of a sorted array in the original one and swapped them.
But now the challenge comes to identify the corresponding subtrees, and I have no idea how to derive that from the inorder traversal.
First of all, if the tree has duplicate values and they are not always stored at the same side of their parent (that has the same value) then it is not always possible to detect a swap. Imagine a tree with the same value in many different places:
______ 8 _____
/ \
_ 8_ ___ 8 __
/ \ / \
2 8* 8* 14
/ \ / \ / \ / \
1 3 8 8 8 8 13 15
This is a valid BST. And if we were to swap the two subtrees marked with an asterisk, we would end up with a valid BST, and so there is no way to detect which subtrees were swapped. It could well have been the children of the first *-node that had been swapped, or the children of the second *-node that had been swapped. There is no way to know this.
So, it is only possible to detect a swap, if the result of the swap inserts the two involved subtrees at invalid positions. One way to ensure this, is to dictate that duplicate values should always be stored at the same side (for example at the right) of the parent node that has the same value.
Algorithm
An in-order traversal is a good idea, but the idea to then verify that the visited nodes come out in their right order is less useful.
Instead, during the traversal, keep track of the "window" (a min-max range) between which values are allowed in the currently visited subtree. As soon as you find a child that has a value outside that window, report that child node as being misplaced, and don't continue in that child's subtree (as we may assume that the subtree itself is a consistent BST).
If there was indeed a single swap, you will find two such anomalies.
Code
Here is some code (actually JavaScript), assuming you have a Node class with the usual value, left and right properties, and duplicate values can only be stored at the right of a parent node having the same value. The function takes as argument the root node of the BST:
function findSwap(root) {
let results = []; // This array (stack) will be filled with 2 nodes
// Recursive function, which will populate the array:
function recur(node, min, max) {
if (node.value < min || node.value >= max) { // Out of range!
results.push(node); // log this node, and don't bother recurring deeper
} else {
if (node.left != null) {
recur(node.left, min, node.value); // Narrow the window
}
if (node.right != null) {
recur(node.right, node.value, max); // Narrow the window
}
}
}
// Start the search with an infinite window
recur(root, -Infinity, Infinity);
return results; // Return the two nodes found as an array of nodes
}
Note that the out-of-range condition needs exactly those inequalities:
node.value < min || node.value >= max
The min value represents an allowable value, but the max does not. So the valid value range of a node is [min, max) (including min, excluding max). This follows from the extra requirement that duplicate values should always be stored at the right side. If you would decide to always store them on the left side, then the equality should be allowed on the min value and not the max value.
Implementation
Below is a runnable snippet which first creates this binary search tree:
______ 8 _____
/ \
_ 4_ __ 12 __
/ \ / \
2 6 10 14
/ \ / \ / \ / \
1 3 5 7 9 11 13 15
It then swaps the subtree at 6 with the subtree at 10. And finally it calls the above function and reports the result:
function findSwap(root) {
let results = [];
function recur(node, min, max) {
if (node.value < min || node.value >= max) {
results.push(node);
} else {
if (node.left) {
recur(node.left, min, node.value);
}
if (node.right) {
recur(node.right, node.value, max);
}
}
}
recur(root, -Infinity, Infinity);
return results;
}
// Define the Node class
class Node {
constructor(value) {
this.value = value;
this.left = this.right = null;
}
add(...values) { // Allow adding more than one value with one call
for (let value of values) {
if (value < this.value) {
if (this.left) this.left.add(value);
else this.left = new Node(value);
} else {
if (this.right) this.right.add(value);
else this.right = new Node(value);
}
}
}
}
// Demo:
// Create a complete binary tree with values 1 through 15
let root = new Node(8); // root
root.add( 4, 12, // level 1
2, 6, 10, 14, // level 2
1, 3, 5, 7, 9, 11, 13, 15); // level 3
// Perform a swap of the subtree rooted in 6 and in 10:
[root.left.right, root.right.left] = [root.right.left, root.left.right];
// Call the function:
let result = findSwap(root);
// Report which subtrees were swapped
console.log(result[0].value, result[1].value); // 10, 6
Of course, if the tree did not have a swap of exactly two distinct subtrees, then the returned array will not always give reliable information, since it assumes that a wrongly attached subtree is itself still consistent.
But if the returned array is empty, you may conclude that the BST is fine.
Detecting move of one subtree
In comments you gave an example of a subtree that was moved (not swapped with another):
In that case the above code will return just the misplaced subtree, but it will not give information about where this subtree came from.
If also this case should be covered, then we need to change the output, because it doesn't really help to list the other (degenerate) "subtree" as null. So then I propose to have the output state which is the parent and the side of the edge where the subtree was cut away.
The above algorithm could be adapted so that it will do some post processing in case there is only one anomaly found: in that case a simple binary search will find the insertion spot for that misplaced subtree. This post processing represents O(logn) time complexity, so it does not impact the overall linear time complexity.
Here is the adapted code, together with the example you had posted:
function findSwap(root) {
let results = [];
function recur(node, parent, side, min, max) {
if (node.value < min || node.value >= max) {
results.push({parent, side, node});
return;
}
if (node.left != null) {
recur(node.left, node, "left", min, node.value);
}
if (node.right != null) {
recur(node.right, node, "right", node.value, max);
}
}
recur(root, null, "root", -Infinity, Infinity);
// Post processing:
if (results.length === 1) {
// It was not a swap, but a move
let value = results[0].node.value;
// Look up the insertion point for the misplaced value (and its subtree)
let parent = root;
while (results.length < 2) {
if (value < parent.value) {
if (parent.left == null) {
result.push({parent, side: "left", node: null });
} else {
parent = parent.left;
}
} else {
if (parent.right == null) {
results.push({parent, side: "right", node: null });
} else {
parent = parent.right;
}
}
}
}
return results;
}
// Define the Node class
class Node {
constructor(value) {
this.value = value;
this.left = this.right = null;
}
add(...values) { // Allow adding more than one value with one call
for (let value of values) {
if (value < this.value) {
if (this.left) this.left.add(value);
else this.left = new Node(value);
} else {
if (this.right) this.right.add(value);
else this.right = new Node(value);
}
}
}
}
// Demo (as in image):
let root = new Node(5); // root
root.add( 3, 8, // level 1
2, 4, 7, 9); // level 2
// Perform the move of the subtree rooted in 8, below the node 4
root.left.right.right = root.right;
root.right = null;
// Call the function:
let result = findSwap(root);
// Report which subtrees were swapped
function edgeName(edge) {
return "the " + edge.side + " child (" + (edge.node?.value??null) + ") of node " + edge.parent.value;
}
console.log(edgeName(result[0]) + " was swapped with " + edgeName(result[1]));
I stumbled upon an algorithm problem of which I want an optimised approach.
Here goes,
Suppose I have a linked-list which is sorted. Each element of the linked list may have a down pointer which contains a List which is sorted too.
What is the best memory and time efficient way to merge such a list with the subsequent down list?
For eg,
1 -> 5 -> 10 -> 60 -> 100
| | |
20 50 101
| |
30 70
This should get converted to:
1 -> 5 -> 10 -> 20 -> 30 -> 50 -> 60 -> 70 -> 100 -> 101
Data structure for linked list:
Node {
Node next;
List down;
Integer value;
}
Thanks in advance :)
Here is the link to the solution :
https://www.geeksforgeeks.org/flattening-a-linked-list/
Just to give you a brief idea of the post on this link:
Start from leftmost node of list, and you need follow the merge step of Merge sort.
This merge will happen between right node(right of 1 which is 5) down list, and down list( down of 1 which is null) of leftmost node.
You need to create a new flattened list, and add to this list the nodes after comparison between 2 lists.
Keep on moving forward in your main list after merging 2 down lists.
The simplest and efficient enough would be scanning the whole 'main' list, unlinking each 'down list' and appending it to the main one, and finally natural-merge sorting the resulting list as a whole.
Idea:
Traverse through the original linked list and merge the linked lists of the elements accordingly.
This is a code written in c++, this is an iterative approach but you can also write similarly write the recursive approach which would, of course, look simple by no of lines, but not O(1). So, better use the iterative approach :
// same logic merging two sorted arrays
Node* merge(Node *head1, Node *head2) {
struct Node *end = NULL;
struct Node *start = NULL;
// merge till one of the linked list is completely traversed
while (head1 != 0 and head2 != 0) {
if (head1->data <= head2->data) {
if (end == NULL) {
start = head1;
end = start;
}
else {
end->bottom = head1;
end = end->bottom;
}
head1 = head1->bottom;
}
else {
if (end == NULL) {
start = head2;
end = head2;
}
else {
end->bottom = head2;
end = end->bottom;
}
head2 = head2->bottom;
}
}
// check for the remaining elements in linked list which was not traversed completely
if (head1 != NULL) {
end->bottom = head1;
}
else {
end->bottom = head2;;
}
return start;
}
Node *flatten(Node *root)
{
// base condition
if (root == NULL || root->next == NULL) {
return root;
}
// merge the linked list of elements accordingly
Node *prev = root, *to = root->next;
while (to != NULL) {
prev = merge(prev, to);
to = to->next;
}
return prev;
}
I wanted to sort a linked list containing 0s, 1s or 2s. Now, this is clearly a variant of the Dutch National Flag Problem.
http://en.wikipedia.org/wiki/Dutch_national_flag_problem
The algorithm for the same as given in the link is:
"Have the top group grow down from the top of the array, the bottom group grow up from the bottom, and keep the middle group just above the bottom. The algorithm stores the locations just below the top group, just above the bottom, and just above the middle in three indexes. At each step, examine the element just above the middle. If it belongs to the top group, swap it with the element just below the top. If it belongs in the bottom, swap it with the element just above the bottom. If it is in the middle, leave it. Update the appropriate index. Complexity is Θ(n) moves and examinations."
And a C++ implementation given for the same is:
void threeWayPartition(int data[], int size, int low, int high) {
int p = -1;
int q = size;
for (int i = 0; i < q;) {
if (data[i] == low) {
swap(data[i], data[++p]);
++i;
} else if (data[i] >= high) {
swap(data[i], data[--q]);
} else {
++i;
}
}
}
My only question is how do we traverse back in a linked list like we are doing here in an array?
A standard singly-linked list doesn't allow you to move backwards given a linked list cell. However, you could use a doubly-linked list, where each cell stores a next and a previous pointer. That would let you navigate the list forwards and backwards.
However, for the particular problem you're trying to solve, I don't think this is necessary. One major difference between algorithms on arrays and on linked lists is that when working with linked lists, you can rearrange the cells in the list to reorder the elements in the list. Consequently, the algorithm you've detailed above - which works by changing the contents of the array - might not actually be the most elegant algorithm on linked lists.
If you are indeed working with linked lists, one possible way to solve this problem would be the following:
Create lists holding all values that are 0, 1, or 2.
Remove all cells from the linked list and distribute them into the list of elements that are equal to 0, 1, or 2.
Concatenate these three lists together.
This does no memory allocation and purely works by rearranging the linked list cells. It still runs in time Θ(n), which is another plus. Additionally, you can do this without ever having to walk backwards (i.e. this works on a singly-linked list).
I'll leave the complete implementation to you, but as an example, here's simple C++ code to distribute the linked list cells into the zero, one, and two lists:
struct Cell {
int value;
Cell* next;
}
/* Pointers to the heads of the three lists. */
Cell* lists[3] = { NULL, NULL, NULL };
/* Distribute the cells across the lists. */
while (list != NULL) {
/* Cache a pointer to the next cell in the list, since we will be
* rewiring this linked list.
*/
Cell* next = list->next;
/* Prepend this cell to the list it belongs to. */
list->next = lists[list->value];
lists[list->value] = list;
/* Advance to the next cell in the list. */
list = next;
}
Hope this helps!
As others have said, there is no way to "back up" in a linked list without reverse links. Though it's not exactly an answer to your question, the sort can be easily accomplished with three queues implementing a bucket sort with three buckets.
The advantage of queues (vice pushing on stacks) is that the sort is stable. That is, if there are data in the list nodes (other than the 0,1,2-valued keys), these will remain in the same order for each key.
This is only one of many cases where the canonical algorithm for arrays is not the best for lists.
There is a very slick, simple way to implement the queues: circularly linked lists where the first node, say p, is the tail of the queue and consequently p->next is is the head. With this, the code is concise.
#include <stdio.h>
#include <stdlib.h>
typedef struct node_s {
struct node_s *next;
int val;
int data;
} NODE;
// Add node to tail of queue q and return the new queue.
NODE *enqueue(NODE *q, NODE *node)
{
if (q) {
node->next = q->next;
q->next = node;
}
else node->next = node;
return node;
}
// Concatenate qa and qb and return the result.
NODE *cat(NODE *qa, NODE *qb)
{
NODE *head = qa->next;
qa->next = qb->next;
qb->next = head;
return qb;
}
// Sort a list where all values are 0, 1, or 2.
NODE *sort012(NODE *list)
{
NODE *next = NULL, *q[3] = { NULL, NULL, NULL};
for (NODE *p = list; p; p = next) {
next = p->next;
q[p->val] = enqueue(q[p->val], p);
}
NODE *result = cat(q[0], cat(q[1], q[2]));
// Now transform the circular queue to a simple linked list.
NODE *head = result->next;
result->next = NULL;
return head;
}
int main(void)
{
NODE *list = NULL;
int N = 100;
// Build a list of nodes for testing
for (int i = 0; i < N; ++i) {
NODE *p = malloc(sizeof(NODE));
p->val = rand() % 3;
p->data = N - i; // List ends up with data 1,2,3,..,N
p->next = list;
list = p;
}
list = sort012(list);
for (NODE *p = list; p; p = p->next)
printf("key val=%d, data=%d\n", p->val, p->data);
return 0;
}
This is now a complete simple test and it runs just fine.
This is untested. (I will try to test it if I get time.) But it ought to be at least very close to a solution.
Using a doubly linked list. If you have already implemented a linked list object and the related link list node object, and are able to traverse it in the forward direction it isn't a whole bunch more work to traverse in the reverse direction.
Assuming you have a Node object somewhat like:
public class Node
{
public Node Next;
public Object Value;
}
Then all you really need to do is change you Node class and you Insert method(s) up a little bit to keep track of of the Node that came previously:
public class Node
{
public Node Next;
public Node Previous;
public Object Value;
}
public void Insert(Node currentNode, Node insertedNode)
{
Node siblingNode = currentNode.Next;
insertedNode.Previous = currentNode;
insertedNode.Next = siblingNode;
if(siblingNode!= null)
siblingNode.previous = insertedNode;
currentNode.next = insertedNode;
}
PS Sorry, I didn't notice the edit that included the C++ stuff so it's more C#
Works for all cases by CHANGING NODES rather than NODE DATA.. Hoping its never too late!
METHOD(To throw some light on handling corner cases):
1. Keep three dummy nodes each for 0,1,2;
2. Iterate throught the list and add nodes to respective list.
3. Make the next of zero,one,two pointers as NULL.
4. Backup this last nodes of each list.
5. Now handle 8 different possible cases to join these list and Determine the HEAD.
zero one two
0 0 0
0 0 1
0 1 0
0 1 1
1 0 0
1 0 1
1 1 0
1 1 1
An implementation of this in C++.
Node* sortList(Node *head)
{
struct Node dummyzero,dummyone,dummytwo;
dummyzero.next = dummyone.next = dummytwo.next = NULL;
struct Node *zero =&dummyzero,*one = &dummyone,*two=&dummytwo;
Node *curr = head,*next=NULL;
while(curr)
{
next = curr->next;
if(curr->data==0)
{
zero->next = curr;
zero = zero->next;
}
else if(curr->data==1)
{
one->next = curr;
one = one->next;
}
else
{
two->next = curr;
two = two->next;
}
curr = next;
}
zero->next = one->next = two->next =NULL; //Since this dummynode, No segmentation fault here.
Node *zerolast = zero,*onelast = one,*twolast = two;
zero = dummyzero.next;
one = dummyone.next;
two = dummytwo.next;
if(zero==NULL)
{
if(one==NULL)
head = two;
else
{
head = one;
onelast->next = two;
}
}
else
{
head = zero;
if(one==NULL)
zerolast->next = two;
else
{
zerolast->next = one;
onelast->next = two;
}
}
return head;
}
The idea is to use dutch flag sorting algorithm, with a slight modification:
sort 0's and 1's as per dutch flag method,
But for 2's instead of adding them at the end of list, keep them in a separate linked list.
And finally append the 2's list to the sorted list of 0's and 1's.
Node * sort012_linked_list(Node * head) {
if (!head || !head->next)
return head;
Node * head_of_2s = NULL;
Node * prev = NULL;
Node * curr = head;
while (curr) {
if (curr->data == 0) {
if (prev == NULL || prev->data == 0) {
prev = curr;
curr = curr->next;
}
else {
prev->next = curr->next;
curr->next = head;
head = curr;
curr = prev->next;
}
}
else if (curr->data == 1) {
prev = curr;
curr = curr->next;
}
else { // curr->data == 2
if (prev == NULL) {
head = curr->next;
curr->next = head_of_2s;
head_of_2s = curr;
curr = head;
}
else {
prev->next = curr->next;
curr->next = head_of_2s;
head_of_2s = curr;
curr = prev->next;
}
}
}
if (prev)
prev->next = head_of_2s;
return head;
}
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;
}