Avl tree how to calculate balances

algorithm - trees - red black tree

Lots and lots of heat here, but not a lot of light, so let's see if we can provide something.

First an RB tree is an associative data structure, unlike an array that cannot accept a key and return an associated value unless it is an integer "key" in a 0% savings index of connected integers. An array can't get any bigger either (yes, I know my way around realloc () too, but under the covers that need a new array and then a memcpy ()). So if you have any of these requirements, an array won't work. .. The storage efficiency of an array is perfect. Zero waste, but not very smart, or flexible - Realloc () won't withstand.

Secondly In contrast to a bsearch (), an RB tree can dynamically grow dynamically (AND shrink) on an array of elements, which is an associative data structure. The bsearch () works well for indexing a data structure of a known size that will maintain that size. If you don't know the size of your data in advance, or if new items need to be added or deleted, a bsearch () is not available. Bsearch () and qsort () are both well supported in classic C and have good memory efficiency, but are not dynamic enough for many applications. They're my personal favorite because they're quick and easy, and when you're not dealing with real-time apps, they are often flexible enough. Additionally, in C / C ++ you can sort an array of pointers to records, point to the struc {} member you want to compare, and then rearrange the pointers in the pointer array so that the pointers are read in order. At the end of the pointer, Sort outputs your data in sorted order. These in-memory data files are extremely memory-efficient, quick, and relatively easy to use. All you have to do is add a few "*" to your comparison function (s).

Third In contrast to a hash table, which must also be of a fixed size and cannot even be fed, an RB tree will automatically grow and balance itself to maintain its O (log (n)) performance guarantee. In particular, if the key of the RB tree is an int, it can be faster than a hash because while the complexity of a hash table is O (1), it can be a very expensive hash computation. A tree's 1-stroke multiple integer comparison often outperforms 100-stroke + hash calculations, not to mention rewarming and malloc () space for hash collisions and restores. Finally, if you want ISAM access as well as key access to your data, a hash is ruled out because, in contrast to the natural arrangement of the data in a tree implementation, there is no order of the data inherent in the hash table. The classic use for a hash table is to provide key access to a table of reserved words for a compiler. The storage efficiency is excellent.

Fourth and the linked or doubly linked list, which, in contrast to an array, naturally supports element insertions and deletions and thus changes its size, is very low in every list. It is the slowest of all data structures because each element only knows how to get to the next element. So you have to search for (element_knt / 2) links on average to find your date. It is mainly used where insertions and deletions are common somewhere in the middle of the list, and especially where the list is circular and feeds an expensive process that makes the time to read the links relatively small. My general RX is to use any large array instead of a linked list when your only requirement is that it be able to grow in size. If you have exceeded the size of an array, you can reconfigure a larger array (). The STL does this "under the roof" for you when you use a vector. Raw, but potentially 1,000 times faster if you don't need inserts, deletions, or key lookups. Storage efficiency is poor, especially with doubly linked lists. In fact, a doubly linked list that requires two pointers is just as inefficient as a red and black tree while having NONE of its appealing, fast, ordered retrieval properties.

Fifth Trees support many more operations on their sorted data than any other data structure. For example, many database queries make use of the fact that a range of leaf values ​​can be easily specified by specifying their common parent and then focusing subsequent processing on the part of the tree that the parent "owns". The potential for multithreading offered by this approach should be evident, as only a small area of ​​the tree needs to be locked - namely, only the nodes owned by the parent and the parent themselves.

In short, trees are the Cadillac of data structures. You pay a heavy price in terms of storage used, but you get a completely self-maintaining data structure. For this reason, as pointed out in other answers here, transactional databases use trees almost exclusively.