Why does switching parent nodes not switch its children nodes? - c++

For example, in this question: https://leetcode.com/problems/invert-binary-tree/
The correct solution is:
TreeNode* invertTree(TreeNode* root) {
if(root!=NULL)
{
TreeNode* tmp = (root->left);
root->left=root->right;
root->right=tmp;
invertTree(root->left);
invertTree(root->right);
}
return root;
}
However, why can we not just simply do:
TreeNode* invertTree(TreeNode* root) {
if(root!=NULL)
{
TreeNode* tmp = (root->left);
root->left=root->right;
root->right=tmp;
}
return root;
}
Wouldn't switching the parent nodes of the subtrees also switch its children?

Start with a tree (at least three levels):
A
/ \
B C
/ \ / \
D E F G
Swap the left and right children of the root:
A
/ \
C B
/ \ / \
F G D E
Notice that you are not yet at the inverted tree:
A
/ \
C B
/ \ / \
G F E D

Swapping the left and the right pointers only swaps the pointers, but the subtree pointers (further down) also have to be inverted. That's why you have to recurse down the left and right trees.

Related

My segment tree update function doesn't work properly

The problem:
In this task, you need to write a regular segment tree for the sum.
Input The first line contains two integers n and m (1≤n,m≤100000), the
size of the array and the number of operations. The next line contains
n numbers a_i, the initial state of the array (0≤a_i≤10^9). The following
lines contain the description of the operations. The description of
each operation is as follows:
1 i v: set the element with index i to v (0≤i<n, 0≤v≤10^9).
2 l r:
calculate the sum of elements with indices from l to r−1 (0≤l<r≤n).
Output
For each operation of the second type print the corresponding
sum.
I'm trying to implement segment tree and all my functions works properly except for the update function:
void update(int i, int delta, int v = 0, int tl = 0, int tr = n - 1)
{
if (tl == i && tr == i)
t[v] += delta;
else if (tl <= i && i <= tr)
{
t[v] += delta;
int m = (tl + tr) / 2;
int left = 2 * v + 1;
int right = left + 1;
update(i, delta, left, tl, m);
update(i, delta, right, m + 1, tr);
}
}
I got WA on segment tree problem, meanwhile with this update function I got accepted:
void update(int i, int new_value, int v = 0, int tl = 0, int tr = n - 1)
{
if (tl == i && tr == i)
t[v] = new_value;
else if (tl <= i && i <= tr)
{
int m = (tl + tr) / 2;
int left = 2 * v + 1;
int right = left + 1;
update(i, new_value, left, tl, m);
update(i, new_value, right, m + 1, tr);
t[v] = t[left] + t[right];
}
}
I really don't understand why my first version is not working. I thought maybe I had some kind of overflowing problem and decided to change everything to long longs, but it didn't help, so the problem in the algorithm of updating itself. But it seems ok to me. For every segment that includes i I need to add sum of this segment to some delta (it can be negative, if for example I had number 5 and decided to change it to 3, then delta will be -2). So what's the problem? I really don't see it :(
There are 2 problems with your first solution:
The question expects you to do a point update. The condition (tl == i && tr == i) checks if you are the leaf node of the tree.
At leaf node, you have to actually replace the value instead of adding something into it, which you did for the second solution.
Secondly, you can only update the non-leaf nodes after all its child nodes are updated. Updating t[v] before making recursive call will anyways result into wrong answer.

Resolving a puzzle (optimal solution)

I have a puzzle 3x3 of numbers as follow:
3 | 5 | 2
7 | 8 | 9
1 | 6 | 4
Being the solution:
1 | 2 | 3
4 | 5 | 6
7 | 8 | 9
The rule is that I can only move nearby "pieces" until I get the solution.
My take on this was to calculate the offset and then run it into a "fancy" algorithm for an efficient solution. However, I can only think of using bruteforce and checking the amount of steps the program did to find the most efficient one.
In offset I mean:
(2, 0) | (0, 1) | (-1, 0)
(0, 1) | (0, 1) | ( 0, 1)
(0, -2) | (1, -1) | (-2, -1)
Which are the offsets of x and y in a cartesian plan. I got the following which does calculate the offset, but no thoughts on the "fancy algorithm".
https://ideone.com/0RP83x
Is there a efficient way to get the least movements for the solution without using bruteforce ?
It is possible to consider the grid as a node (part of a graph).
Let's write the grid
abc
def
ghi
as a single line abcdefghi.
You start with node 352789164 and you want to reach node 123456789.
The neighbours of a node are all the nodes you can reach by applying swaps.
e.g 123456789 has for neighbours
[
213456789, 132456789,
123546789, 123465789,
123456879, 123456798,
423156789, 153426789,
126453789, 123756489,
123486759, 123459786
]
Then you can apply A*, by supplying:
d(nodeA, nodeB) = weight(nodeA, nodeB) = 1 (all swaps cost 1)
h(node) = minimal number of swaps needed to get to solution.
To have the minimal h, consider counting the misplaced digits.
If you have an even number of misplaced digits, you need at minimum "half of it" swaps
If you have an odd number of misplaced digits, then half + 1 (e.g 312 for goal 123 needs 2 swaps)
Below example in js where I copy pasted code from wiki
function h (node) {
const s = ''+node
let misplaced = 0
for(let i = 0; i < s.length; ++i) {
if (parseInt(s[i]) != i+1) {
misplaced++
}
}
if (misplaced % 2 === 0) {
return misplaced / 2
}
return Math.ceil(misplaced / 2)
}
function d (a, b) {
return 1
}
const swaps = (_ => {
const arr = [[1,2],[2,3],[4,5],[5,6],[7,8],[8,9],[1,4],[2,5],[3,6],[4,7],[5,8],[6,9]]
function makePermFunc([a,b]) {
a--
b--
return function (node) {
const s = (''+node)
const da = parseInt(s[a])
const db = parseInt(s[b])
const powa = 9 - a - 1
const powb = 9 - b - 1
node -= da * 10**powa
node -= db * 10**powb
node += da * 10**powb
node += db * 10**powa
return node
}
}
const funcs = arr.map(makePermFunc)
return node => funcs.map(f => f(node))
})();
//https://en.wikipedia.org/wiki/A*_search_algorithm
function reconstruct_path (cameFrom, current) {
const total_path = [current]
while(cameFrom.has(current)) {
current = cameFrom.get(current)
total_path.unshift(current)
}
return total_path
}
// A* finds a path from start to goal.
// h is the heuristic function. h(n) estimates the cost to reach goal from node n.
function A_Star(start, goal, h) {
// The set of discovered nodes that may need to be (re-)expanded.
// Initially, only the start node is known.
const openSet = new Set([start])
// For node n, cameFrom[n] is the node immediately preceding it on the cheapest path from start to n currently known.
const cameFrom = new Map()
// For node n, gScore[n] is the cost of the cheapest path from start to n currently known.
const gScore = new Map()
gScore.set(start, 0)
// For node n, fScore[n] := gScore[n] + h(n).
const fScore = new Map()
fScore.set(start, h(start))
while (openSet.size) {
//current := the node in openSet having the lowest fScore[] value
let current
let bestScore = Number.MAX_SAFE_INTEGER
for (let node of openSet) {
const score = fScore.get(node)
if (score < bestScore) {
bestScore = score
current = node
}
}
if (current == goal) {
return reconstruct_path(cameFrom, current)
}
openSet.delete(current)
swaps(current).forEach(neighbor => {
// d(current,neighbor) is the weight of the edge from current to neighbor
// tentative_gScore is the distance from start to the neighbor through current
const tentative_gScore = gScore.get(current) + d(current, neighbor)
if (!gScore.has(neighbor) || tentative_gScore < gScore.get(neighbor)) {
// This path to neighbor is better than any previous one. Record it!
cameFrom.set(neighbor, current)
gScore.set(neighbor, tentative_gScore)
fScore.set(neighbor, gScore.get(neighbor) + h(neighbor))
if (!openSet.has(neighbor)){
openSet.add(neighbor)
}
}
})
}
// Open set is empty but goal was never reached
return false
}
console.log(A_Star(352789164, 123456789, h).map(x=>(''+x).split(/(...)/).filter(x=>x).join('\n')).join('\n----\n'))
console.log('a more basic one: ', A_Star(123654987, 123456789, h))

Calculating AVL tree node balance from it's children nodes' balances

Say I have an AVL tree such that it's nodes store their own balance factor as a single integer.
How can I calculate the balance factor of a node N if I know the balance factor of both it's left and right child.
Note that I DO NOT have the rHeight and lHeight, so bal(N) = lHeight - rHeight is not an option.
Short answer - you can't.
Long answer:
Consider these two trees:
A
/ \
B C A
/ \ / \ / \
D E F G B C
/ \ / \ / \ / \
H I J K L M N O
They have the same balance factor, but they aren't the same height.
So, if you only have the balance factor of the child, you don't know how high that subtree is, thus you can't use only that to calculate the balance factor of the parent.

How to rotate a treap or AVL-tree?

Sorry to bother you guys again, but I have a question and i haven't figured it out on my own for several days.
It is about the rotation of a treap, for example, to right rotate a treap at pos.
The question is how to link (or connect) pos->left to pos's original parent?
I found this code online, which works, but i didn't see how it solves my question, is it because of the use of *&? If so, could you help me explain it a little bit?
And what is the function of pos=b is this code?
void Treap::right_rotate(Node *&pos) {
Node *b = pos->left;
pos->left = b->right;
b->right = pos;
pos = b;
}
Thanks in advance!!
The tricky part is indeed the *& part. That declares it as a reference to a pointer (here's a link or two to some similar sample code, but I fear they may be more confusing than helpful).
By changing out the node to which the pointer points with pos = b, you can swap the contents to the different node without having to know the parent. The original reference is updated to be the new rotated node.
Here's a diagram just in case you needed a little overkill of what the rotation looks like (though it sounds like you understand that part).
Initial condition:
Node *&pos;
|
[P]
/ \
L R
/ \ / \
w x y z
You then store the left child since you are about to overwrite it as far as P is concerned.
Node *b = pos->left;
pos->left = b->right;
|
L [P]
/ \ / \
w x R
/ \
y z
Now we finish the rotation since since L is floating in space, breaking proper tree structure:
b->right = pos;
L
/ \ |
w [P]
/ \
x R
/ \
y z
We then finish the upkeep by updating the reference to the node pointer to be the new node that replaces the contents of that place in memory:
pos = b;
|
[L]
/ \
w P
/ \
x R
/ \
y z
Whomever was previously pointing to pos (pos's original parent) now points to the same spot in memory, but that value has now been replaced with the child that has been rotated.

finding height of a tree in sml

i want to find the height of a tree in sml.The tree is not a regular one it could have any number of nodes at a level.Futher the datatypes that it holds is also abstract.could someone help me out with it.
As other have said, then please post what ever definition of a tree you have, and what code you have come up with so far.
I assume that you have already defined your own tree structure or you have had it defined in the assignment, anyways this ought not to be your problem so here is simple binary tree structure using a Node and an empty Leaf as constructors.
datatype 'a tree = Leaf
| Node of ('a tree) * 'a * ('a tree)
val t1 = Node (Leaf, 1, Leaf)
val t2 = Node (t1, 2, Leaf)
val t3 = Node (Leaf, 3, Leaf)
val t = Node (t2, 4, t3)
Ascii representation of t
4
/ \
/ \
2 3
/ \ / \
1 * * *
/ \
* *
Where * represents the leafs
Given this representation of a binary tree, you could create a function that calculates the height in a bottom up maner. You mainly have to consider two cases:
What are the height of a tree only containing a leaf?
What are the height of a Node that has a left sub-tree of height l and a right sub-tree of height r?
If we look at t2 from the above example
2
/ \
1 *
/ \
* *
Then obviously the right sub-tree has height x (depends on how you define the height of leafs) and the left sub-tree has height 0. The Height of t2 must then be 1 (0+1).
Considering t then it has a left sub-tree of height 1 (as we have just found out) and the right sub-tree has height 0. Thus t must have height 2 (1+1)
I have seen many quick implementation of a height function that counts the root node, but this is not correct.
Here
height is defined as the number of links from the root to the deepest leaf