Talk:AVL tree

message: Now that you have removed the 4 language pages, your presentation on AVL Trees is almost non-existent. Come on guys, it has been more than 50 years since the invention of AVL Trees - is that the best you can do?NNcNannara (talk) 03:21, 9 August 2016 (UTC)
thread_title: Vacuous Page - No Content

message: Nowhere in this article is a mention of what these trees are used for. Which problem do they solve ?  — Preceding unsigned comment added by 2A01:E35:1382:320:845A:88D5:419:48D0 (talk) 13:05, 31 July 2015 (UTC)
thread_title: What is it for ?

message: balance factor = height of left subtree minus height of right subtree. read CLRS book for more info  — Preceding unsigned comment added by 98.209.224.234 (talk) 23:44, 28 March 2013 (UTC)
thread_title: Balance Factor?

message: The term balance factor is mentioned several times in this article but not really explained. I understand what an unbalanced tree is generally but I do not know what balance factor is exactly (or how to calculate it etc) and this article makes no attempt at introducing it (or linking to it somewhere else). I think it is reasonable to assume people learning about AVL's might also not know about balance factors and they (balance factors) should be clarified or linked early in the article. Just my 2c.  — Preceding unsigned comment added by 24.87.108.195 (talk) 01:51, 25 July 2012 (UTC)
thread_title:  Comment 

message: Quoting from the article:
:Deletion from an AVL tree may be carried out by rotating the node to be deleted down into a leaf node, and then pruning off that leaf node directly. Since at most log n nodes are rotated during the rotation into the leaf, and each AVL rotation takes constant time, the deletion process in total takes O(log n) time.
:Practically, this is a large overhead and complex to program. Therefore, it's more common to implement a lazy deletion -- leave the deletion target in place, flag it as "deleted", and replace it with an inserted node if they would occupy the same spot.
I assume that the tree will not (usually) be balanced after a lazy deletion, so an implemention which uses lazy deletion is not strictly an AVL tree.--Malcohol 15:53, 28 June 2006 (UTC)
replies: text: Actually, as long as you "clean out" the tree whenever it falls below a certain percentage full, such as 50%, I think you still get amortized O(log n) operations. In any case, whether or not this is "properly" an AVL tree, it's pretty clearly a very simple variation on one. Deco 11:54, 29 June 2006 (UTC)
replies: text: If you eagerly delete any node that has at most one child, then at most one half of all nodes will be pending deletion.
While we're on the topic of deletion (operation description missing btw), the text quoted above mentions rotating a node downwards into a leaf. One may also rotate a node downwards until it has only one child, and delete it by replacing it by its only child. Jesselong 18:45, 30 October 2006 (UTC)
thread_title:  Lazy deletion 

message: In the depicted unbalanced and balanced trees, the balancing of the leftmost 3-element subtree doesn't appear to be able to be done by tree rotations as they are defined on the tree rotations page.  When the 9 is rotated out and the 14 in, the twelve will switch to the opposite side, maintaining the imbalance.  When this imbalance is "fixed" by another rotation, it will simply be returned to its original state.  Thus, this subtree can never be balanced by rotations.  Clearly, it is a special case for implementation, and should be noted either on this page or the tree rotations page.  I intend to do so if no one objects. --Quintopia 22:13, 10 November 2006 (UTC)
replies: text: Well, I don't think the article necessarily needs to explain how how to convert an arbitrary binary search tree like that 3-element subtree you mentioned into an AVL tree. But I agree, it would be interesting to state an algorithm how to do it. A simple one might be to create an empty tree, then walk the original unbalanced tree in-order, and insert each node into the new tree, using the AVL-insert. That should take O(n*log n). --Allefant 14:24, 24 November 2006 (UTC)
thread_title:  Problem? 

message: There are some diagrams of AVL trees at :Commons:Category:AVL-trees that may be helpful. Deco 06:43, 21 February 2007 (UTC)
thread_title:  Diagrams 

message: the example section got needlessly complex with references to null structures... I did a rewrite of that section, feel free to adjust or rever to a previous version if you like. I also removed the images because rotations aren't covered in this article directly, but in the tree rotation article. McKay 22:32, 14 May 2007 (UTC)
thread_title: Rewrite

message: I removed the image again for a couple of reasons:
*The image doesn't seem to fit anywhere. We don't have a section on rotations, we've deferred most of that concept to the Tree rotation page.
*The image is inaccurate. I doesn't adequately show how to perform a rotation, specifically, it doesn't show what to do with the other children of the pivot. McKay 15:43, 16 May 2007 (UTC)
replies: text: Maybe we should add a small section about rotations here? McKay 18:12, 16 May 2007 (UTC)
thread_title: Image

message: I reintegrated a selected few of Mikkalai's massive rm of links (as I was looking for one which I thought I had seen once). It is quite accepted with other data structures, that a maximum of one implementation per programming language is linked, as an example for interested students and programmers. However, I collected them under a new title Implementations rather than under the previous External Links. Is this acceptable also for you, Mikkalai? --Gulliveig 02:46, 3 November 2007 (UTC)
replies: text: External link lists should be collected under the "external links" section. I realize that links to AVL tree source code are very relevant and useful, but I dislike long external link lists because they invite everyone to add their own favourite to the list, so they build up cruft over time and degrade into uselessness again; not to mention the problem with spammers. Coming up with a non-arbitrary criteria for external links is very hard. -- intgr [talk] 22:33, 3 November 2007 (UTC)
thread_title: Implementations

message: To help the beginners understand, I think comparision is very important. For example, comparision between insertion and deletion, comparision with other self-balancing trees, etc. Visame (talk) 19:59, 7 June 2008 (UTC)
replies: text: I think an explanation which people who do not understand AVL can read and then understand AVL is very useful.  What we have now is utterly lacking.  It does not fully describe the algorithm and it can anyway only be understood by people who *already* understand how AVL works.  Toby Douglass (talk) 10:43, 27 March 2009 (UTC)
thread_title: Comparision

message: The balance factor of a node is the height of its left subtree minus the height of its right subtree.
However, in the rotations list we have:
Right-Right case and Right-Left case: If the balance factor of P is +2, then the right subtree outweighs the left subtree of the given node
Left-Left case and Left-Right case: If the balance factor of P is -2, then the left subtree outweighs the right subtree of the given node
These statements are contradiction.  The left minus the right would yield a +2 if the left subtree outweighs the right one. Not the other way.  Am I missing somethingMichael miceli (talk) 20:34, 15 October 2009 (UTC)
thread_title:  Contradiction 

message: I must say that the diagrams for post-insertion rebalancing are beautiful! Whoever originally did them did a good job. They very clearly show what's going on, and I would suggest that if anyone has some time, to create some equally descriptive and nicely-coloured ones for the post-deletion rebalancing cases as well. Troglodyto (talk) 19:36, 25 February 2010 (UTC)
thread_title:  Diagrams for Insert and Delete 

message: I think the picture in the "Deletion" is not correct because we're talking about nodes with one child, and it shows a node with two children. Am I wrong ?
Guitow (talk) 20:33, 27 April 2010 (UTC)
replies: text: The image is correct. Moberg (talk) 15:54, 23 November 2010 (UTC)

text: What the poorly captioned image is trying to say is as follows: (middle tree) If we want to delete a node with two children, such as "7". We can either (left tree) write a "6" where the "7" was and delete the "6"; or we can (right tree) write a "9" where the "7" was and delete the "9". In either case we're now trying to delete a node with only one child, which is a simpler problem. What's not in the diagram is that removing a node with a single child may-or-may-not involve rebalancing the tree. So, if we hit a case where removing the "6" requires rebalancing but removing the "9" doesn't, then we obviously choose to remove the "6". Clear? :p 132.165.76.2 (talk) 09:58, 5 January 2011 (UTC)
thread_title:  Deleting diagram 

message: After deleting a node, I end up with a unbalanced tree that can be fixed with wither a right-right followed by right-left rotation or only a right-left rotation. Which one should I choose? To get the situation: Draw the tree by inserting {1, 3, 2, 4} (without rotating for balance). Moberg (talk) 15:54, 23 November 2010 (UTC)
thread_title:  Deleting leaves an ambigous rotation situation 

message: * Conventionally, the balance factor is computed by subtracting the height of the right subtree from the left; I say conventionally since all the books and academic papers I read are that way...
* The sentence: "If the balance factor of R is ≤ 0" is wrong and confusing, it should be: If the balance factor of R is < 0, same for the mirror case... (not when you inserting anyway...)
* And this article doesn't really talk about how to adjust balance factors all the way to the top of the tree...
— Preceding unsigned comment added by Codingrecipes (talk • contribs) 00:43, 3 March 2011 (UTC)
thread_title:  Issues with this article 

message: The third paragraph needs a citation for the sentence, "however, red-black trees are faster for insertion and removal."  Both insertion and removal are logarithmic for finding the place for the operation, but the rebalancing is where they differ.  One source that compares the number of operations for each type of tree is Comparison of Binary Search Trees (BSTs).  Two sources that state the time for AVL trees are 8.3 AVL Trees and Balanced Binary Search Trees.  One source that states the time for red-black trees after insertion is 9. Red-Black Trees.  It might be easier to use a source that includes information on both trees in the same place.  The first link I gave does this, and my blog post does this as well.  It would be flattering to have that cited, but perhaps a source without the excessive bantering that gets right to the point would be ideal.  I am unsure about the guidelines for sources on Wikipedia pages which is why I have listed these five. ComputerGhos (talk) 08:36, 9 May 2012 (UTC)
replies: text: Most blogs are not regarded as reliable sources, as anyone can create a blog and write anything they like there. Looking at the three non-blog sources you mention, although they all contain some relevant material, as far as I can see none of them actually gives a comparison of speed of insertion and removal for AVL and red-black trees, which is what is needed. JamesBWatson (talk) 09:02, 9 May 2012 (UTC)
thread_title:  A source for the "citation needed" 

message: The article states that
balanceFactor = height(left-subtree) - height(right-subtree)
But then uses if (balance_factor(L) > 0) to test if subtree L is taller on the right than on the left, breaking consistency. I think we should change the definition of balance factor to:
balance-factor = height(right-subtree) - height(left-subtree)
This supports the intuition that -1 means "left-heavy" and +1 means "right-heavy".
Joeyadams (talk) 15:27, 18 July 2013 (UTC)
thread_title:  Inconsistent sign for balance factor 

message: Knuth defines the the bounds of an AVL tree as a function of the size of the tree where the size of the tree is defined as the number of interior nodes. In other instances the size of the tree is defined as the total number of nodes. The wikipedia entry on binary trees for example is inconsistent in this regard. On that page the text defines size as the number of internal nodes but the figure defines the size as the number of total nodes.  — Preceding unsigned comment added by 173.79.116.101 (talk) 20:05, 8 February 2014 (UTC)
thread_title:  AVL Tree Bounds 

message: Let us first assume the balance factor of a node L is 2 (as opposed to the other possible unbalanced value -2).
: OK
This case is depicted in the left column of the illustration with L=5.
: OK, I see the left column.
We then look at the left subtree (the larger one) with root P.
: Yes sir, I am looking.
If this subtree does not lean to the right - i.e. P has balance factor 0 or 1 -
: I see. Balance factor is left height - right height, hence it has to be positive. But what happens when the balance factor is > 1?
we can rotate the whole tree to the right to get a balanced tree.
: WHAT THE F**K??? ARE YOU KIDDING ME?? What is a 'whole' tree? Is it like whole grain? Whatever happened to L? And P? What does it mean to rotate a tree? Who wrote this piece of shit?
This is labelled as the "Left Left Case"
Rotating a whole tree means rotating the top most node of the subtree you are looking at. The height of every node changes, hence you are rotating the whole tree. Technically in the alternating case where you rotate the subtree you're also rotating an entire tree just not the one identified by the balance anomaly which is one higher and has a whole tree on the other side that gets pushed down by the rotation.
: I am enlightened!
Could someone who actually knows how this algorithm works rewrite this section? The current section has been written by someone who hates knowledge.--Cubancigar11 (talk) 07:07, 7 April 2014 (UTC)
replies: text: Some simple amendments. --Nomen4Omen (talk) 19:44, 1 February 2016 (UTC)
thread_title:  Are you kidding me? 

message: Every reference cited lists the average complexity of insert and delete as O(log n). This is because an insert or delete operation is considered to be done without regard to the state of the tree. The operation must start at the root node of the tree and search until it finds the appropriate place to either insert or delete the desired element. There is no dependence on any previous traversal of the tree for this operation to happen.  — Preceding unsigned comment added by Jmonty42 (talk • contribs) 21:38, 29 September 2015 (UTC)
replies: text: It is quite common to list the average complexity of insert and delete as O(log n). The above contribution also states: "The operation must start at the root node of the tree". But this is not absolutely true. Assume a tree having more than one access path to an object, e.g. a free storage management system with two access paths to each free space chunk, one with size as key, which will be used at storage acquisition, and the second with start address, which will be used at storage return. At storage acquisition, a chunk of sufficient size has to be searched for, removed from the set of free chunks in both trees and a possible remainder reentered into the set of free chunks in both trees. The walk from the node in the size-tree to the node in the address-tree can be accomplished within the chunk, so that no second search (for the address-chunk) is required. So in case the size fits exactly, we have a deletion (size-tree) with O(log n) and a deletion (address-tree) with a deletion cost where the operation does not start at the root node, it can start at the target node so that no searching is required. The walk from the node in the size-tree to the node in the address-tree is one (1!) instruction. For most balanced BSTs the worst case update cost amounts to O(log n), but on average it is O(1). If the size does not fit exactly, we have additionally to reinsert the remaining size (requiring a second size-search). In the address tree, because the chunk is already in correct (address-)sort order, we can immediately reuse the node. Thus, the cost is from 1 search and 2 mere (= without search) deletions up to 2 searches and 2 mere deletions and 2 mere insertions.At storage return time, the user arrives with (start address, size). This has to be checked for conflicts with present free chunks. If there is no conflict it has to be looked for adjacent free chunks, so that these can be joined to make up a bigger free chunk. Thus we have, in the non-adjacent case, an insertion (address-tree) with search and O(log n) and an insertion (size-tree) with search and O(log n). The check for adjacency requires a 1-step traversal in both directions, address up and address down, which also amounts to O(log n) in the worst case, but on average is O(1). So, at storage return time we have 2 search operations, although we maintain at least two trees and in each tree up to three objects, i.e. we update from at least 2 up to 6 objects altogether.The only source of which I know so far, that to some extent separates search cost from mere update cost, is Mehlhorn [7 Sorted Sequences]. On p.158 under "7.4 Amortized Analysis of Update Operations": "Theorem 25. Consider an (a, b)-tree with b ≥ 2a that is initially empty. For any sequence of n insert or remove operations, the total number of split (p.151) or fuse(p.152) operations is O(n)." (Split or fuse are needed only for rebalancing operations.) And on p.165: "AVL trees do not support constant amortized update costs."Because O(log n) and O(1) always sum up to O(log n) there is IMHO nothing wrong when stating: update cost is O(log n) in the worst case and O(1) on average when search is not included. So I would appreciate very much to find another and maybe more explicit source for this separation. --Nomen4Omen (talk) 17:24, 1 February 2016 (UTC)
replies: text: Refer to our previous discussion on the Red-Black Tree talk page. Firstly, the data structure you describe with multiple access paths to each node is NOT a binary search tree, AVL tree, or any other tree-like data structure as defined by anyone. Every single source that has been cited on any page about this has noted that you cannot insert into a binary search tree without searching first. Please carefully read the source you cited. In the opening paragraph of section 7.4 it reads "In the best case, we basically pay for locating the affected element, for updating the sequence, and for updating the bottommost internal node." It clearly states that searching must be included in insertion into a binary search tree. There is no logical way to consider it otherwise and nothing you have ever cited supports that. The example you give above is nonsensical and irrelevant to discussions about binary search trees. The data structure you describe is by definition not a binary search tree. Jmonty42 (talk) 02:22, 8 February 2016 (UTC)
replies: text: Dear User:Jmonty42, you are right: the data structure I described above is NOT ONE (1!) binary search tree – it is TWO (2!) binary search trees, combined into ONE data structure. And it is only ONE example of combining data structures in an application. There are certainly lots of other applications which combine data structures together in one application. I chose this one, because it has an inherent motivation, although there are certainly lots of other applications, where it is useful to have secondary, tertiary etc. access paths to a node besides the intrinsic binary search. (But of course, if they shall have some motivating power they can not be totally simple. And I do not claim that I found the simplest one.)You partially repeat what I said in the first sentences of my above contribution that I do not know of a source which explicitly modularizes INSERT and DELETE into SEARCH and UPDATE costs – except that citation from Mehlhorn. His statement that "AVL trees do not support constant amortized »update« costs" would be totally pointless if modularisation between lookup and update would not be possible. He knows and we all know that »update« costs for RB trees are indeed constant on average as they are for AVL trees. So he makes this statement for marking a (small) advantage of RB trees over AVL trees, an advantage which were completely nonsensical and irrelevant as you would say if modularisation at this point were impossible. No need to stress that software modularisation is principally a good thing. It allows to  the modules in a way useful to an application with other modules, twice, and three or more times.And if modularisation is possible (of course it is) and is foreseen from the beginning, there is no need to quote e.g. this (as you say: nonsensical and irrelevant) example of free storage management. (And btw, modularisation is already halfway foreseen in the articles and by all authors in that SEARCH is a module of its own. What if the application has to take a look at the data before deleting; and if it decides to delete, has it to search for the second time with the same result?)Finally, it is not a crime to look for a source – in this case for one which explicitly takes into account modularisation. --Nomen4Omen (talk) 17:33, 8 February 2016 (UTC)
thread_title:  Insertion/Deletion average complexity 

message: I've tried making an implementation from this article. It is very close to functional however this article has not helped in a way that I think goes beyond any kind of confusion about academic, legacy or field specific language. It is almost as though someone has mangled it to stop people copying and pasting or reading and rewriting into assignments. It just isn't written well.
It mixes several styles of demonstrating things and I'm not sure if that's because of multiple authors or something else (someone writing each part in whichever way seems easiest). However it gets progressively worse, perhaps because people haven't gone all the way through it. It gets worst on deleting a node. It is written in a way that seems over complicated to me and even makes no sense in parts. Consider this:
"Let node X be the node with the value we need to delete, and let node Y be a node in the tree we need to find to take node X's place, and let node Z be the actual node we take out of the tree."
"4. Choose node Z to be all the child and parent links of old node Y = those of new node X."
How can node Z be a node but then be a set of edges? How can we take any node out of the tree but X? Even if we swap X with Y, we're still removing X from the tree. Here it suggests to create a temporary node Z which is a copy of old Y but actually the new X which we already have after swapping so it's redundant. I find the concept of Z as described in the article to be really confusing and it seems like someone's implementation quirk that requires a virtual node but then it does not make sense because why would you delete the virtual node in a later step and not X? In reality I only see three real nodes directly in play.
* Always: The node to delete (X).
* Sometimes: The node to swap the node to delete with (Y). -- This operation should have no side effects regarding the following operations.
* Sometimes: The node to replace X with (Z). -- This may be null in most implementations with a check needed only for updating its parent.
Y in play if count_children(original(X)) == 2, Z in play if count_children(updated(X)) == 1
As far as I can establish so far all you need to do is swap X with a candidate further down if there is one so that your delete affects as little as possible (occurs on a leaf or on a node containing only one leaf).
# If X has less than two children go to 4.
# Let Y be closest value to X starting with either one of its children (I choose the highest one or arbitrarily if equal). You can do this with the same search used for insertion reusing the value of X starting with the chosen child (assumes values are unique). Simpler, if you choose left, then keep going right until you can't because going left is moving further away from X and vice versa. Y is guaranteed to have one leaf child or no children with any child being more distant to X.
# Swap all of the parent child links for X and Y, including the respective child links in their parents (may be root). The tree structure is now identical although the order is no longer preserved (X is now out of order but that is acceptable as it is to be deleted). If node identity is unimportant, you may simply swap the value of the two nodes then let X be Y.
# If X has a child let Z be that child otherwise let Z be null (empty).
# Replace X with Z so that X's parent now points to Z instead (or update root with Z if X is root) and if Z is not null let Z's parent be X's parent. X will no longer exist in the tree. It can be deleted now but its parent will need to be preserved for the next step.
# Letting N be Z and P being the parent of X retrace the tree back up the path correcting the balance as needed (while instead of do while).
# Explicitly delete X if necessary.
6 should now integrate with the pseudo code which can be halved as the code for the other side is the same with left/right and 1/-1 swapped. On second taught, 6 has a problem if X is empty. The first iteration should go by which ever side X was on. Perhaps a simply approach is to delete X last of all and use it to seed N.
The pseudo code also is a bit misleading as far as I can tell as it doesn't manage updating the balance factors after a rotation. For the alternate case it's a small distinction/optimisation but you don't need to double rotate. You can update only the relations needed in a single action.
I have not verified that the above is 100% correct in all cases so I have not attempted to update the article.
I have made a working implementation which passes full testing. I believe much of the problem at least concerning the pseudo code is that implementation is not trivial. I've seen algorithms elsewhere that can be implemented completely from the pseudocode or are well abstracts giving a complete overview. The former is unlikely to be possible here. Some have tried but haven't been able to get it right. There are a lot of specific details when it comes to implementation as well as varying approaches. The depth that parts of this article go to is inconsistent and ultimately arbitrary. One category of details will be included here but not there. One format here and another there.
I suggest a single format should be the target of this article when describing steps in implementation. Either well abstracted pseudo code from someone who has a good working implementation in particular with less duplication of symmetrical cases (use words such as opposite, alternating, etc) or in the list form but written in a way that is less waffle and more abstract about differences, for example, just swap X and Y.
It isn't completely useless. I did manage to make a good implementation from this. However the article caused far more confusion and impedance than I think it really should have to if written to the expected standard.
— Preceding unsigned comment added by 2001:978:2300:30A:2FC6:5A8A:5E23:429 (talk) 19:42, 24 February 2016 (UTC)
thread_title:  Article to implementation - Contains Jibberish - Sabotage? 

message: Please read carefully the major wikipedia policy WP:NOR and don't write texts in wikipedia articles without backing all statements with references from reliable sources. - üser:Altenmann >t 15:23, 24 July 2016 (UTC)
thread_title:  Original research 

message: It’s really a shame what happened to the article five months ago on 24. Jul. 2016. Since then the article is missing almost completely the sections most important to the subject, namely the ones about the modifying operations insert and delete. For these operations the data structure has been invented at its time, but the article no longer reflects this.
The destruction has been verbally justified by „rm unreferened original computer science research“ or here, in Talk:AVL tree, by „don't write texts ... without backing all statements with references from reliable sources“. A closer look at the old article would have shown that there is not really original computer science research (maybe it is kind of Synthesis of published material) and that especially the code portions have been missing references. But for the main text there were reliable references such as Georgy Adelson-Velsky, Evgenii Landis; Knuth; Sedgewick; Pfaff; Alexander. Anyway, for calling for more or better references there could have been other means than total erasure. However, also the rather old template messages in sections Searching and Traversal about additional citations have not been very encouraging to authors all the time for five months now. Almost nothing essential has happened since then. So the question remains: Why?  — Preceding unsigned comment added by 92.203.216.3 (talk) 07:21, 28 November 2016 (UTC)
thread_title:  Article in ruins 

message: AVL Trees have a very functional structures and using a functional programming language like haskell highly simplifies the code. Haskell removes all the boilerplate and brings the implementation very close to pseudocode. See https://gist.github.com/gerard/109729 Vishal0123 (talk) 01:11, 3 May 2017 (UTC)
thread_title:  Changing language to haskell? 

message: Sorry, as far as I can see you are a newcomer.
Sorry, you are wrong.
Please read the text carefully. I guess everything is explained.
Y is never the inserted node. Y is a subtree. The inserted node could be the Z of section #insert.
Maybe you find an even better explanation. But the statements are correct. --Nomen4Omen (talk) 20:06, 7 May 2017 (UTC)
thread_title:  Changes by [[user:Thislooksfun]] 

message: In a couple of the sections on manipulating AVL trees (e.g. Insert), there are large blocks of c / pseudocode examples. It might be better to collapse those blocks (e.g. with  and ), to make the pseudocode take up less space on the page. As-is, if you're just looking for a conceptual overview, the large blocks of code tend to break up the flow of the article (especially on mobile, where some of them take up about three screen-lengths each). Thoughts? disgruntledGM ❮talk / contribs❯ 02:00, 18 February 2019 (UTC)
replies: text: I went ahead and made the change. Feel free to comment / move things around / revert if necessary. I couldn't find a good way of collasping the last two examples without it awkwardly affecting the placement of the diagrams, but it's probably not really necessary to collapse those, anyway. disgruntledGM ❮talk / contribs❯ 08:11, 19 February 2019 (UTC)
thread_title:  Collapsing the pseudocode 

message: Where did this insert algorithm shown in the "Example code" come from? It is not the same as the traditional algorithm as described in Knuth's The Art of Computer Programming and elsewhere. JCG (talk) 19:52, 21 February 2023 (UTC)
thread_title:  Algorithm source?