have been learning sorting algorithms, have not been in the list of lists too much effort, because not much. Recently see STL Source code, only to find that the original even the list, can also have time complexity for O (NLOGN) algorithm,
Much to my surprise, I can usually think of an insertion sort.
The following code is written according to the source (remove the template to increase readability), note that forward_list is the c++11 new one-way list, this is chosen because it is closer to our own implementation of the list when the practice.
void Sort_list (forward_list<int>& l) {Auto it = L.begin (); if (L.empty () | | ++it = = l.end ()) return;forward_list& Lt;int> carry;forward_list<int> counter[64];//A total of only 64 barrels, because the first bucket is filled when the inside of the most 2^i elements, 2^64, far beyond the general number of elements int fill = 0 ; Fill records which bucket is currently filled in while (!l.empty ()) {Carry.splice_after (Carry.cbefore_begin (), L, L.cbefore_begin ());// Each time an element is removed from the original list, int i = 0;while (i < fill &&!counter[i].empty ()) {counter[i].merge (carry); Carry.swap (counter[i ++]);} Carry.swap (Counter[i]); if (i = = fill) ++fill;} for (int i = 1; i < fill; ++i) Counter[i].merge (counter[i-1]); L.swap (Counter[fill-1]);}
On the analysis of this algorithm: Online a lot of debate on whether this is a quick sort or merge sort (Houtie's book is a quick line).
To understand this code, you can run it manually.
Fill, the record used a few barrels, the outermost loop guarantees the fact that the No. 0 bucket into the fill-1 bucket inside, either empty, or stored with 2^fill elements, and is an ordered list.
Each bucket merged with the newly removed element (stored in the carry) is counter[0]. If there is no element in the No. 0 bucket, put it directly in Carry.swap (Counter[i]). The next round of circulation
Time, because counter[0] has elements, it will enter the inner loop, when Counter[i].merge (carry) makes the No. 0 bucket into a list of two elements, and then the inner loop second step, and this list
Transfer to carry, the next round of inner loop, with two elements of the carry will be to merge with the 1th bucket (if the 1th bucket is not empty), if the first bucket is empty, it will exit the inner loop and put the element into the first bucket, (at this time i = = Fill, Then fill becomes 2) and the next outer loop continues to take the next element from the list, (at this time counter[0] is empty, counter[1] contains two elements), as before, first found counter[0] is empty, into the inner layer of the loop, The element is then filled directly into the counter[0], the next outer loop takes an element, enters the inner loop, merges with Counter[0], swaps, and then the next round of inner loop, the carry with two elements will merge with the counter[1 with two elements], swap, i = = Fiil = = 2 exits the inner loop, four elements change to the 2nd bucket, fill++.
After walking through this, it feels clear, but in addition to the cyclic invariant conditions of the outer loop, it is difficult to think of this in the thought of basic quick or merge sorting.
List sorting in STL