What is the difference between complete binary tree, almost complete binary tree and perfect binary tree? [duplicate] - binary-tree

This question already has answers here:
Difference between "Complete binary tree", "strict binary tree","full binary Tree"?
(13 answers)
Closed 1 year ago.
What is the difference between complete binary tree, almost complete binary tree and perfect binary tree?
In my institute professor told they are different but on certain sites they have been merged almost complete binary tree and (complete binary tree and perfect binary tree as same). Now I am very much confused so had to ask world's largest tech community. Please help. Thankyou!

To answer the question in part, this Wikipedia article states the following.
In a complete binary tree every level, except possibly the last, is completely filled, and all nodes in the last level are as far left as possible.
A perfect binary tree is a binary tree in which all interior nodes have two children and all leaves have the same depth or same level.
However, it is also pointed out that this terminology is not well-standardized.

Related

Why is Binary Tree Data Structure better that Linear?

Why Binary Tree data structure considered as better than when compared to linear data structures? Please explain with a suitable diagram.
(Posted on behalf of the OP).
A binary tree is special because when you are searching it you repeatedly decide whether to follow the left branch or the right branch eliminating half of the tree each time (assuming the tree reasonably well is balanced). In fact, this is what you do each time you add a node.
Take a look at http://www.computersciencebytes.com/array-variables/binary-trees/.

Binary tree challenge example [closed]

As it currently stands, this question is not a good fit for our Q&A format. We expect answers to be supported by facts, references, or expertise, but this question will likely solicit debate, arguments, polling, or extended discussion. If you feel that this question can be improved and possibly reopened, visit the help center for guidance.
Closed 9 years ago.
I have been watching some lectures from the excellent Richard Buckland and experimenting with binary trees but I don't completely understand how to implement one. Below is how far I have got.
class Tree(object):
def __init__(self, val, left=None, right=None):
self.val = val
self.left = left
self.right = right
t = Tree(4, Tree(2, Tree(1), Tree(3)), Tree(6, Tree(5), Tree(7)))
Could somebody refer me to a simple example problem which can be solved using a binary tree. I don't really understand what data I will be presented with to create the tree or how I could use it practically. I'm scared to google for some examples because I don't want somebody else's source code. I want to work out the implementation myself. But before I can do this I feel I need a problem to solve. Ideally, I would like a couple fairly trivial example problems and then a few more intermediate problems.
Your code above is a "valid" implementation of a binary tree... it's already complete. You have nodes (which you call Trees) and each node can have 0, 1, or 2 children. edit Actually I just realized that you can't implement an empty tree using your implementation, but that's a small nitpick.
This is a semantic thing but it's "sort of important". A binary tree by itself isn't really used for problems at all. A standard binary tree is not really useful--it's just a tree where each node has at most two children. This link should clarify what I'm saying (and probably contains a sufficient answer to your question): https://stackoverflow.com/a/2159506.
I think what you're actually interested in is a "balanced binary search tree" which has extra properties. In particular, it's "ordered" from the left to right (that's a vague description, but I don't want to be hand-wavy and say that the "left child is less than the parent and its sibling" when it could actually be equal in some implementations). It also has a O(log(n)) bounded depth (you won't have trees of height n with n objects in it... which is just a linked list).
Anyways, to answer your question: it's sort of boring, but a common suggestion is to implement an abstract data structure such as a heap or dictionary. Note the terminology: a heap can be implemented using a binary search tree. A heap, by definition, is not tied to any implementation. It only requires that certain operations can be performed on it (e.g. peek(), min(), add(), etc). Choosing a primitive data structure like a binary tree is necessary to produce a heap (otherwise it's just this abstract thing floating in your head). Choosing a balanced binary search tree also gives time complexities to those operations (e.g. a heap implemented with a balanced binary search tree has O(log(n)) peek(). See the wiki link for more details: http://en.wikipedia.org/wiki/Heap_(data_structure)#Comparison_of_theoretic_bounds_for_variants).
Once you've written a heap, you can look at any problem whose algorithm uses a heap... there's a lot. Say you want to find the kth largest element in linear time. Heap (proving this is a bit tricky though). What if you want to implement Prim's algorithm? Heap. What if you want to sort arbitrary objects with worst case O(n log(n))? Heapsort (note that usually people don't use heap sort since it's not actually fast).
Well, try this: http://www.spoj.com/problems/TREE/
Or this: http://www.spoj.com/problems/THREECOL/
http://www.spoj.com/problems/NWERC11B/
These problems are not trivial, and will ask time, but you will definitely learn from this.
Basically, there is a vast number of problems that essentially need binary trees in some way. For example, building an inference algorithm in propositional logic.
And yes, if you can get a hold of Sedgewick's algorithms, there are chapters about binary search trees, for example, pretty useful.

How is balancing of binary trees implemented?

I'm studying how to balance trees and I have some questions
Is it possible to balance a normal binary tree? If yes, which algorithm should be used?
Do I necessarily have to use a AVL or Red-black tree to obtain a balanced tree? How do these work?
I read something about rotations, weights but I'm kind of confused right now
Is it possible to balance a normal binary tree? If yes, which
algorithm should be used?
In O(n) you can build a complete tree, and populate it with the elements in in-order traversal.
It cannot be done better, because A BST might in rare cases decay to a chain (linked list), where all nodes have one son as null. In this cases, accessing the element in the middle is O(n) itself.
Do I necessarily have to use a AVL or Red-black tree to obtain a
balanced tree?
There are other balanced trees such as B+ trees, and other data structures (not trees) such as skip-lists. You might want to have a look at a list of known data structures, especially the trees section.
How do these work?
I find the wikipedia articles both on AVL tree and Red-Black tree very informative. If you have something specific you don't understand there - you should ask.
Also: Trying to implement a balanced trees on your own (Implement a known tree, not inventing a new one - of course) - is great for educational purposes, and by doing so - you will definitely understand how it works.
Well... AVL and red-black trees are "normal binary trees" that are balanced, and keep that balance (for some definition of "balanced"). I'm not a computer science teacher to come up with my own explanation of the algorithms, and I guess you aren't looking for a cut&paste from Wikipedia :-)
Now, for balancing binary trees: if the tree is a search tree (i.e. 'sorted', but 'balanced' doesn't really make all that much sense if it's not) you could always just recreate the tree. The simplest algorithm is to use an array with all the elements from the tree, in sorted order (easily obtained from an inorder traversal). Then build an algorithm around this general idea:
take the middle element of the array as the root of the tree. This will create a tree node, and two arrays "left" and "right", which are meant to form the left and right subtrees
Apply this same algorithm recursively to create a tree from the "left" array and one from the "right" array. These two trees become the children of the parent node.
You might have to be careful with the case when the array has an even number of elements: there is no obvious "middle element", and removing one of the two candidates will create arrays of different sizes. I'm too lazy to analyze this further to see if that could offset the whole balancing thing.
Of course, doing something like this every time you change the tree isn't such a great idea; you really want to use self-balancing trees like AVL for that. Doing it after creating the tree might not be all that useful either: you could just use the array itself and do binary searches on it, instead of making a tree. The array IS just another form of a binary tree...
EDIT: there is a reason why a lot of computer scientists have spent a lot of time developing data structures and algorithms that perform well in certain situations. Rolling your own version of a balanced binary tree is unlikely to beat these...
Can you balance an unbalanced tree?
Yes, You can. You use the same balance function you created for your AVL Tree inside a PostOrderTraversal function.
Should You Do it?
No!!! You should recreate it! Balancing the tree will cost you unnecessarily.
How do I recreate it?
Use an InOrderTraversal function to put your nodes into an array. Then use a variable that will always go to the middle of the array and the left middle, right middle and add the nodes to the new Tree.
Is it possible to balance a normal binary tree? If yes, which algorithm should be used?
Do I necessarily have to use a AVL or Red-black tree to obtain a balanced tree? How do these work?
In general, Trees are either unbalanced or balanced. AVL, Red-Black, 2-3, e.t.c. are just trees with some properties and according to their properties they use some extra variables and functions. Those extra variables and function can also be used in the "normal" binary trees. In other words those functions and variables are not bounded to their respective type of tree. The nodes of a "normal" binary tree always had a balance! You just didn't use it because you didn't care if the "normal" binary tree was balanced or not. They also always had a height, depth, e.t.c. You just didn't care. In general, you will realize at one point that all are a trade-off between speed and memory. If you know what you are doing, more memory usage will make your program faster. Less memory usage means more calculations so you will have a slower program.

Where red-black trees are useful [duplicate]

This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
Red-Black Trees
I started watching a lecture at mit on red-black trees and after 15 minutes gave up.
Sure, I have not watched the previous 10 lectures but why no real world example before going into the theory?
Can someone give an example and explain why red-black trees are an essential data structure?
Red-black trees are self-balancing, and so can insert, delete, and search in O(log n) time. Other types of balanced trees (e.g. AVL trees) are often slower for insert and delete operations.
In addition, the code for red-black trees tends to be simpler.
They are good for creating Maps or associative arrays, and special-purpose data stores. I used one in a high speed telecom application to implement a least-cost routing system.
Note: I haven't seen the lecture.
Red-black trees are binary search trees that are self-balancing when an item is added or removed. This feature guarantees that every search within this tree has O(logn) complexity.
If you construct a tree without balancing it, it is possible to create a degenrated tree that is effectively a linked list with O(n) complexity.
Wikipedia says "self-balancing binary search tree".
"Put very simply, a red–black tree is a binary search tree that inserts and deletes in such a way that the tree is always reasonably balanced."
Which helps when data happens to be sorted. Without the balancing the tree devolves to a linked list.
Wikipedia provides an explanation and an important example.
Red-black trees provide worst-case guarantees for insertion time, deletion time and search time. This can be very useful for real time applications.
A real world example is the Completely Fair Scheduler in the Linux kernel.

Create a balanced binary search tree from a stream of integers

I have just finished a job interview and I was struggling with this question, which seems to me as a very hard question for giving on a 15 minutes interview.
The question was:
Write a function, which given a stream of integers (unordered), builds a balanced search tree.
Now, you can't wait for the input to end (it's a stream), so you need to balance the tree on the fly.
My first answer was to use a Red-Black tree, which of course does the job, but i have to assume they didn't expect me to implement a red black tree in 15 minutes.
So, is there any simple solution for this problem i'm not aware of?
Thanks,
Dave
I personally think that the best way to do this would be to go for a randomized binary search tree like a treap. This doesn't absolutely guarantee that the tree will be balanced, but with high probability the tree will have a good balance factor. A treap works by augmenting each element of the tree with a uniformly random number, then ensuring that the tree is a binary search tree with respect to the keys and a heap with respect to the uniform random values. Insertion into a treap is extremely easy:
Pick a random number to assign to the newly-added element.
Insert the element into the BST using standard BST insertion.
While the newly-inserted element's key is greater than the key of its parent, perform a tree rotation to bring the new element above its parent.
That last step is the only really hard one, but if you had some time to work it out on a whiteboard I'm pretty sure that you could implement this on-the-fly in an interview.
Another option that might work would be to use a splay tree. It's another type of fast BST that can be implemented assuming you have a standard BST insert function and the ability to do tree rotations. Importantly, splay trees are extremely fast in practice, and it's known that they are (to within a constant factor) at least as good as any other static binary search tree.
Depending on what's meant by "search tree," you could also consider storing the integers in some structure optimized for lookup of integers. For example, you could use a bitwise trie to store the integers, which supports lookup in time proportional to the number of bits in a machine word. This can be implemented quite nicely using a recursive function to look over the bits, and doesn't require any sort of rotations. If you needed to blast out an implementation in fifteen minutes, and if the interviewer allows you to deviate from the standard binary search trees, then this might be a great solution.
Hope this helps!
AA Trees are a bit simpler than Red-Black trees, but I couldn't implement one off the top of my head.
One of the simplest balanced binary search tree is BB(α)-tree. You pick the constant α, which says how much unbalanced can the tree get. At all times, #descendants(child) <= (1-α) × #descendants(node) must hold. You treat it as normal binary search tree, but when the formula doesn't apply to some node anymore, you just rebuild that part of the tree from scratch, so that it is perfectly balanced.
The amortized time complexity for insertion or deletion is still O(log N), just as with other balanced binary trees.

Resources