Balanced Binary Search Tree for numbers - binary-tree

I wanted to draw a balanced binary search tree for numbers from 1 to 20.
_______10_______
/ \
___5___ 15
/ \ / \
3 8 13 18
/ \ / \ / \ / \
2 4 7 9 12 14 17 19
/ / / /
1 6 11 16
Is the above tree correct and balanced?

In answer to your original question as to whether or not you need to first calculate the height, no, you don't need to. You just have to understand that a balanced tree is one where the height difference between the tallest and shortest node is zero or one, and the simplest way to achieve this is to ensure that you always pick the midpoint of the possible list, when populating the top node in a sub-tree.
Your sample tree is balanced since all leaf nodes are either at the bottom or next-to-bottom level, hence the difference in heights between any two leaf nodes is at most one.
To create a balanced tree from the numbers 1 through 20 inclusive, you can just make the root entry 10 or 11 (the midpoint being 10.5 for those numbers), so that there's an equal quantity of numbers in either sub-tree.
Then just do that recursively for each sub-tree. On the lower side of 10, 5 is the midpoint:
10
/ \
5 11-thru-19 sub-tree
/ \
1-thru-4 6-thru-9
sub-tree sub-tree
Just expand on that and you'll end up with something like:
_______10_______
/ \
___5___ 15
/ \ / \
2 7 13 17
/ \ / \ / / \
1 3 6 8 11 16 18 <- depth of highest leaf node
\ \ \ \
4 9 12 19 <- depth of lowest leaf node
^
|
Difference is 1
The midpoint can be found at the number where the difference between quantities above and below that numbers is one or zero. For the whole list of numbers 1 through 20 inclusive, there are nine less than 10 and ten greater than 10 (or, if you chose 11 as the midpoint, the quantities are ten and nine).
The difference between your sample and mine is probably to do with the fact that I preferred to pick the midpoint by rounding down where there was a choice (meaning my right sub-trees tend to be "heavier"). Because your left sub-trees are heavier, you appear to have rounded up.
After choosing 10 as the initial midpoint, there's no leeway on the left sub-tree, you have to choose 5 since it has four above and below it. Any other midpoint would result in a difference of at least two between the two halves (for example, choosing 4 as the midpoint would have the two halves of size three and five). This can still give you a balanced sub-tree depending on the data but it's "safer" to choose the midpoint.

Related

convert a tree into a heap using minimum number of changes

Given a k-ary tree, i want to convert it into a min-heap with minimum number of changes. Change is defined as relabelling a node.
one solution i have found is that, i can try a dp solution of changing a nodes value or not changing. But its going to be exponential in time complexity ?
Any ideas, (preferable with optimality proofs).
Example : Say the tree is, 1-3, 3-2, 1-4, 4-5. where 1 is root. Then i can relabel node 3 to 1 or 2, that is in 1 change it becomes a min-heap.
If all you want to do is make sure that the tree satisfies the heap property (the key stored in each node is less than or equal to the keys stored in the node's children), then you should be able to use something like the build-heap algorithm, which operates in O(n).
Consider this tree:
8
-------------
| | |
15 6 19
/ \ | / | \
7 3 5 12 9 22
Now, working from the bottom up, you push each node down the tree as far as it can go. That is, if the node is larger than any of its children, you replace it with the smallest of its children, and you do so until you reach the leaf level, if necessary.
For example, you look at the node valued 15. It's larger than its smallest child, so you swap it, making the subtree:
3
/ \
7 15
Also, 6 swaps places with 5, and 19 swaps places with 9, giving you this tree:
8
-------------
| | |
3 5 9
/ \ | / | \
7 15 6 12 19 22
Note that at the next to leaf level, each node is smaller than its smallest child.
Now, the root. Since the rule is to swap the node with its smallest child, you swap 8 with 3, giving:
3
-------------
| | |
8 5 9
/ \ | / | \
7 15 6 12 19 22
But you're not done because 8 is greater than 7. You swap 8 with 7, and you get this tree, which meets your conditions:
3
-------------
| | |
7 5 9
/ \ | / | \
8 15 6 12 19 22
If the tree is balanced, the entire procedure has complexity O(n). If the tree is severely unbalanced, the complexity is O(n^2). There is a way to guarantee O(n), regardless of the tree's initial order, but it requires changing the shape of the tree.
I won't claim that the algorithm guarantees the "minimal number of changes" for any given tree. I can prove, however, that with a balanced tree the algorithm is O(n). See https://stackoverflow.com/a/9755805/56778, which explains it for binary heap. The explanation also applies to d-ary heap.

How to make a N-level tree in pyramid fashion, such that each child may(doesn't mean has to) have 2 parents?

The question may look very simple, and probably the answer is too, but I always get confused in the tree questions.
Ok so I want to make a tree something like:
3 level 0
/ \
4 5 level 1 ..
/ \ / \
6 7 8
/ \ / \ / \
9 10 11 12
What are such trees called? Sorry, I'm a beginner..
Function can pass an array[] of ints, or function can take input till N = 3 (denoting level 3 with 10 nodes). Also can you give solution in C/C++/Java.
Given your requirements are only for traversal, I would simply implement this using an array a, containing each level as a contiguous sub-array. Level i then occurs in entries L(i-1) up to but not including L(i), where L(n) = n*(n+1)/2. In particular, the jth value on the ith level is in a[L(i-1)+j].
As long as you always keep track of i and j, you can now easily navigate through your pyramid.

Else than backtracking, how do I find longest path in a graph?

I have a graph shaped as a triangle.
8
/ \
1 4
/ \ / \
4 2 0
/ \ / \ / \
9 1 9 4
In the above graph the longest path is {8, 4, 2, 9}
My current algorithm calculates the max number of the adjacent nodes and add it to the list, then calculates the sum of that list. This works in the above graph but won't work in situations such as this scenario:
8
/ \
0 1
/ \ / \
4 0 4
/ \ / \ / \
9 99 3 4
My algorithm will mistakenly go through {8,1,4,4} where the correct longest path is {8,0,4,99}
The only solution I can think of is Backtracking. Where I have to go through all the paths and calculate the max path, which will be insanely slow in a huge graph. This about a 100k nodes graph.
My question is can I do better than this?
Start at the top.
For each node, pick the maximum of its parents (the nodes above connected to it) and add its own value.
Then, in the last row, pick the maximum.
This will just give you the value of the longest path, but you could easily get the actual path by simply starting at the value picked at the bottom and moving upwards, always picking the greater parent.
The running time would be linear in the number of nodes.
Example:
Original:
First example: Second example:
8 8
/ \ / \
1 4 0 1
/ \ / \ / \ / \
4 2 0 4 0 4
/ \ / \ / \ / \ / \ / \
9 1 9 4 9 99 3 4
Output:
First example: Second example:
8 8
/ \ / \
9 12 8 9
/ \ / \ / \ / \
13 14 12 12 9 13
/ \ / \ / \ / \ / \ / \
22 15 23 16 21 111 16 17
Then you'd pick 23 for the first and 111 for the second.
To get the path, we'd have 23-14-12-8, which corresponds to 9-2-4-8, for the first, and 111-12-8-8, which corresponds to 99-4-0-8, for the second.
I'm of course assuming we have a tree, as stated. For general graphs, this problem is quite a lot more difficult - NP-hard, to be exact.
You do not need backtracking here - you can use breadth-first search to propagate the max for the path that you have found so far to the corresponding node, level by level.
Start at the root, and set its max to its own value.
Go through nodes level-by-level
For each node check the max stored in its parent. There may be one or two of these parents. Pick the max of two max-es, add the value of the node itself, and store it in the current node
When the path through the graph is complete, the result would look like this:
Max graph:
8
/ \
8 9
/ \ / \
12 9 13
/ \ / \ / \
21 111 16 17
To recover a path, find the max value in the bottom layer. This is the final node of your path. You can reconstruct the path from the max graph and the original by starting at the max (111), subtracting the value (99), looking for the result (111-99=12) in the max graph, and continuing to that node until you reach the top:
111 - 99 = 12 -- Take 99
12 - 4 = 8 -- Take 4
8 - 0 = 8 -- Take 0
8 is the root -- Take 8
This gives you the max path in reverse. Note that this may not be the unique path (think of a graph filled with equal values to see how there may be multiple max paths). In this case, however, any path that you would recover will satisfy the max path requirement.

Ideal height of tree structure

How can I calculate the ideal height of a tree structure?
When I have this tree
I know the height is 4.
There's a formula that says that the ideal height of a tree is 2 ^ height - 1 but that doesn't make sense to me (since it would be 15).
Can someone please explain?
Well, first of all, that formula applies only to binary trees. Second, the ideal number of nodes in the tree will be 2^height-1. For a saturated binary tree of height 4, the number of nodes will be 15.
That formula is for the maximum number of nodes that can be included in a binary tree of that height. Assuming you want the tree to be as shallow as possible, you want to know the minimum height of such a tree given the number of nodes. So you simply invert:
nodes = 2^height - 1
to get
height = log2(nodes + 1)
rounded up.
Height of the tree is the maximum height among all the nodes in the tree. Now say you have a tree
1
/ \
2 3
/ \ / \
4 5 6 7
the height of the tree is 3(since all path lengths are same so lets say 1-2-5 is maximum) now as there are three levels so no of node at each level
1 =2^0
/ \
2 3 =2^1
/ \ / \
4 5 6 7 =2^2
total =2^0 +2^1+2^2= clearly its a gp with sum 2^3-1 ,hence the number of nodes =2^height-1
if you talk about levels(as they start from 0) no of nodes= 2^(level+1)-1

Binary search tree -- ordering

If we have V values for a search tree where the values are V= {1,2,3,4,5,6,7} inserted from right to left
And we are to order it to get the largest and shortest height possible -- how would we do it? Would it require the best and worst (lg2 (n+1)) case??
And would the orderings be unique?
Thanks -- I kinda understand but am not sure on what steps i should take.
The largest height is easy; put them in order:
1
\
2
\
...
With the smallest height, sort them, take the middle as the root, and put the two sides one either branch. Rinse and repeat.
3
/ \
2 5
/ / \
1 4 6
\
7
So... n for the first one, and log_2(n) for the second (rounded up).
The tallest such trees are created by inserting the values from a sorted sequence
1 2 3 4 5 6 7
or
7 6 5 4 3 2 1
The shortest tree is made by ordering the values via a recursive algorithm that finds the median then processes the left and right subtrees recursively:
4 2 1 3 6 5 7
This produces a tree of logarithmic height:
4
/ \
2 6
/ \ / \
1 3 5 7
Here the median is 4, so that goes first.
4
Now you have a partition for the left (1, 2, 3) and right (5, 6, 7). To order the left, start with its median, 2. Now you have 1 and 3 for its subtrees. These are 1 element sets so that's your base case.
4 2 1 3
Now process your right subtree (5, 6, 7), starting with 6.
4 2 1 3 6 5 7

Resources