QuickHeapsort: Modifications and improved analysis

We present a new analysis for QuickHeapsort splitting it into the analysis of the partition-phases and the analysis of the heap-phases. This enables us to consider samples of non-constant size for the pivot selection and leads to better theoretical bounds for the algorithm. Furthermore we introduce some modifications of QuickHeapsort, both in-place and using n extra bits. We show that on every input the expected number of comparisons is n lg n - 0.03n + o(n) (in-place) respectively n lg n -0.997 n+ o (n). Both estimates improve the previously known best results. (It is conjectured in Wegener93 that the in-place algorithm Bottom-Up-Heapsort uses at most n lg n + 0.4 n on average and for Weak-Heapsort which uses n extra-bits the average number of comparisons is at most n lg n -0.42n in EdelkampS02.) Moreover, our non-in-place variant can even compete with index based Heapsort variants (e.g. Rank-Heapsort in WangW07) and Relaxed-Weak-Heapsort (n lg n -0.9 n+ o (n) comparisons in the worst case) for which no O(n)-bound on the number of extra bits is known.


Introduction
QuickHeapsort is a combination of Quicksort and Heapsort which was first described by Cantone and Cincotti [2]. It is based on Katajainen's idea for Ultimate Heapsort [12]. In contrast to Ultimate Heapsort it does not have any O(n lg n) bound for the worst case running time (lg n = lg 2 n). Its advantage is that it is very fast in the average case and hence not only of theoretical interest.
Both algorithms have in common that first the array is partitioned into two parts. Then in one part a heap is constructed and the elements are successively extracted. Finally the remaining elements are treated recursively. The main advantage of this method is that for the sift-down only ¡one comparison per level is needed, whereas standard Heapsort needs two comparisons per level (for a description of standard Heapsort see some standard textbook, e.g. [6]). This is a severe drawback and one of the reasons why standard Heapsort cannot compete with Quicksort in practice (of course there are also other reasons like cache behavior). Over the time a lot of solutions to this problem appeared like Bottom-Up-Heapsort [19] or MDR-Heapsort [15], [18], which both perform the sift-down by first going down to some leaf and then searching upward for the correct position. Since one can expect that the final position of some introduced element is near to some leaf, this is a good heuristic and it leads to provably good results. The difference between QuickHeapsort and Ultimate Heapsort lies in the choice of the pivot element for partitioning the array. While for Ultimate Heapsort the pivot is chosen as median of the whole array, for QuickHeapsort the pivot is selected as median of some smaller sample (e.g. as median of 3 elements).
In [2] the basic version with fixed index as pivot is analyzed and -together with the median of three version -implemented and compared with other Quickand Heapsort variants. In [8] Edelkamp and Stiegeler compare these variants with so called Weak-Heapsort [7] and some modifications of it (e.g. Relaxed-Weak-Heapsort). Weak-Heapsort beats basic QuickHeapsort with respect to the number of comparisons, however it needs O(n) bits extra-space (for Relaxed-Weak-Heapsort this bound is only conjectured), hence is not in place.
We split the analysis of QuickHeapsort into three parts: the partitioning phases, the heap construction and the heap extraction. This allows us to get better bounds for the running time, especially when choosing the pivot as median of a larger sample. It also simplifies the analysis. We introduce some modifications of QuickHeapsort, too. The first one is in-place and needs n lg n − 0.03n + o(n) comparisons on average what is to the best of our knowledge better than any other known in-place Heapsort variant. We also examine a modification using O(n) bits extra-space, which applies the ideas of MDR-Heapsort to QuickHeapsort. With this method we can bound the average number of comparisons to n lg n − 0.997n + o(n). Actually, a complicated, iterated in-place MergeInsertion uses only n lg n − 1.3n + O(lg n) comparisons, [16]. Unfortunately, for practical purposes this algorithm is not competitive.
Our contributions are as follows: 1. We give a simplified analysis which gives better bounds than previously known. 2. Our approach yields the first precise analysis of QuickHeapsort when the pivot element is taken from a larger sample. 3. We give a simple in-place modification of QuickHeapsort which saves 0.75n comparisons. 4. We give a modification of QuickHeapsort using n extra bits only and we can bound the expected number of comparisons. This bound is better than the previously known for the worst case of Heapsort variants using O(n lg n) extra bits for which best and worst case are almost the same. 5. We have implemented QuickHeapsort, and our experiments confirm the theoretical predictions.
The paper is organized as follows: Sect. 2 briefly describes the basic Quick-Heapsort algorithm together with our first improvement. In Sect. 3 we analyze the expected running time of QuickHeapsort. Then we introduce some improvements in Sect. 4 allowing O(n) additional bits. Finally, in Sect. 5, we present our experimental results comparing the different versions of QuickHeapsort with other Quicksort and Heapsort variants.

QuickHeapsort
A two-layer-min-heap is an array A[1..n] of n elements together with a partition (G, R) of {1, . . . , n} into green and red elements such that for all g ∈ G, r ∈ R we have A[g] ≤ A[r]. Furthermore, the green elements g satisfy the heap condition A[g] ≤ min{A[2g], A[2g+1]}, and if g is red, then 2g and 2g+1 are red, too. (The conditions are required to hold, only if the indices involved are in the range of 1 to n.) The green elements are called "green" because the they can be extracted out of the heap without caution, whereas the "red" elements are blocked. Twolayer-max-heaps are defined analogously. We can think of a two-layer-heap as rooted binary tree such that each node is either green or red. Green nodes satisfy the standard heap-condition, children of red nodes are red. Two-layerheaps were defined in [12]. In [2] for the same concept a different language is used (they describe the algorithm in terms of External Heapsort). Now we are ready to describe the QuickHeapsort algorithm as it has been proposed in [2]. Most of it also can be found in pseudocode in App. D.
We intend to sort an array A[1.
.n]. First, we choose a pivot p. This is the randomized part of the algorithm. Then, just as in Quicksort, we rearrange the array according to p. That means, using n − 1 comparisons the partitioning function returns an index k and rearranges the array A so that for k < j. After the partitioning a two-layerheap is built out of the elements of the smaller part of the array, either the part left of the pivot or right of the pivot. We call this smaller part heap-area and the larger part work-area. More precisely, if k − 1 < n − k, then {1, . . . , k − 1} is the heap-area and {k + 1, . . . , n} is the work-area. If k − 1 ≥ n − k, then {1, . . . , k − 1} is the work-area and {k + 1, . . . , n} is the heap-area. Note that we know the final position of the pivot element without any further comparison. Therefore, we do not count it to the heap-area nor to the work-area. If the heap-area the part of the array left of the pivot, a two-layer-max-heap is built, otherwise a two-layer-min-heap is built.
At the beginning the heap-area is an ordinary heap, hence it is a two-layerheap consisting of green elements, only. Now the heap extraction phase starts. We assume that we are in the case of a max-heap. The other case is symmetric. Let m denote the size of the heap-area. The m elements of the heap-area are moved to the work-area. The extraction of one element works as follows: the root of the heap is placed at the current position of the work-area (which at the beginning is its last position). Then, starting from the root the resulting "hole" is trickled down: always the larger child is moved up into the vacant position and then this child is treated recursively. This stops as soon as a leaf is reached. We call this the SpecialLeaf procedure (Alg. 4.2) according to [2]. Now, the element which before was at the current position in the work-area is placed as red element in this hole at the leaf in the heap-area. Finally the current position in the work-area is moved by one and the next element can be extracted.
The procedure sorts correctly, because after the partitioning it is guaranteed that all red elements are smaller than all green elements. Furthermore there is enough space in the work-area to place all green elements of the heap, since the heap is always the smaller part of the array. After extracting all green elements the pivot element it placed at its final position and the remaining elements are sorted recursively.
Actually we can improve the procedure, thereby saving 3n/4 comparisons by a simple trick. Before the heap extraction phase starts in the heap-area with m elements, we perform at most m+2 4 additional comparisons in order to arrange all pairs of leaves which share a parent such that the left child is not smaller than its right sibling. Now, in every call of SpecialLeaf, we can save exactly one comparison, since we do not need to compare two leaves. For a max-heap we only need to move up the left child and put the right one at the place of the former left one. Summing up over all heaps during an execution of standard QuickHeapsort, we invest n+2t 4 comparisons in order to save n comparisons, where t is the number of recursive calls. The expected number of t is in O(lg n). Hence, we can expect to save 3n 4 + O(lg n) comparisons. We call this version the improved variant of QuickHeapsort.

Analysis of QuickHeapsort
This section contains the main contribution of the paper. We analyze the number of comparisons. By n we denote the number of elements of an array to be sorted. We use standard O-notation where O(g), o(g), and ω(g) denote classes of functions. In our analysis we do not assume any random distribution of the input, i.e. it is valid for every permutation of the input array. Randomization is used however for pivot selection. With Pr [ e ] we denote the probability of some event e. The expected value of a random variable T is denoted by The number of assignments is bounded by some small constant times the number of comparisons. Let T (n) denote the number of comparisons during QuickHeapsort on a fixed array of n elements. We are going to split the analysis of QuickHeapsort into three parts: 1. Partitioning with an expected number of comparisons E[ T part (n) ] (average case).
2. Heap construction with at most T con (n) comparisons (worst case).
3. Heap extraction (sorting phase) with at most T ext (n) comparisons (worst case).
We analyze the three parts separately and put them together at the end. The partitioning is the only randomized part of our algorithm. The expected number of comparisons depends on the selection method for the pivot. For the expected number of comparisons by QuickHeapsort on the input array we ob- 03 g., f (n) = √ n and we assume that we choose the median of f (n) randomly selected elements in time O(f (n)).
As we see, the selection method for the pivot is very important. However, one should notice that the bound for fixed size samples for pivot selection are not tight. The proof of these results are postponed to Sect. 3.3. Note that it is enough to prove the results without the improvement, since the difference is always 0.75n.

Heap Construction
The standard heap construction [9] needs at most 2m comparisons to construct a heap of size m in the worst case and approximately 1.88m in the average case. For the mathematical analysis better theoretical bounds can be used. The best result we are aware of is due to Chen et al. in [5]. According to this result we have T con (m) ≤ 1.625m + o(m). Earlier results are of similar magnitude, by [4] it has been known that T con (m) ≤ 1.632m + o(m) and by [10] it has been known T con (m) ≤ 1.625m + o(m), but Gonnet  During the execution of QuickHeapsort over n elements, every element is part of a heap only once. Hence, the sizes of all heaps during the entire procedure sum up to n. With the result of [5] the total number of comparisons performed in the construction of all heaps satisfies:

Heap Extraction
For a real number r ∈ R with r > 0 we define {r} by the following condition This means that 2 k is largest power of 2 which is less than or equal to r and {r} is the difference to that power, i.e. {r} = r − 2 ⌊lg r⌋ . In this section we first analyze the extraction phase of one two-layer-heap of size m. After that, we bound the number of comparisons T ext (n) performed in the worst case during all heap extraction phases of one execution of QuickHeapsort on an array of size n. Thm. 3.3 is our central result about heap extraction.
The proof of Thm. 3.3 covers almost the rest of Section 3.2. In the following, the height height(v) of an element v in a heap H is the maximal distance from that node to a leaf below it. The height of H is the height of its root. The level level(v) of v to be its distance from the root. In this section we want to count the comparisons during SpecialLeaf procedures, only. Recall that a SpecialLeaf procedure is a cyclic shift on a path from the root down to some leaf, and the number comparisons is exactly the length of this path. Hence the upper bound is the height of the heap. But there is a better analysis.
Let us consider a heap with m green elements which are all extracted by SpecialLeaf procedures. The picture is as follows: First, we color the green root red. Next, we perform a cyclic shift defined by the SpecialLeaf procedure. In particular, the leaf is now red. Moreover, red positions remain red, but there is exactly one position v which has changed its color from green to red. This position v is on the path defined by the SpecialLeaf procedure. Hence, the number of comparisons needed to color the position v red is bounded by The total number of comparisons E(m) to extract all m elements of a Heap H is therefore bounded by Since there are exactly {m} + 1 nodes of level ⌊lg m⌋, there are at most 2 {m} Note that this is an estimate of the worst case, however this analysis also shows that the best case only differs by O(lg m)-terms from the worst case. Now, we want to estimate the number of comparisons in the worst case performed during all heap extraction phases together. During QuickHeapsort over n elements we create a sequence H 1 , . . . , H t of heaps of green elements which are extracted using the SpecialLeaf procedure. Let m i = |H i | be the size of the i-th Heap. The sequence satisfies 2m i ≤ n − j<i m j , because heaps are constructed and extracted on the smaller part of the array.
Here comes a subtle observation: Assume that m 1 + m 2 ≤ n/2. If we replace the first two heaps with one heap H ′ of size |H| ′ = m 1 + m 2 , then the analysis using the sequence H ′ , H 3 , . . . , H t cannot lead to a better bound. Continuing this way, we may assume that we have t ∈ O(lg n) and therefore Later we will replace the m i by other positive real numbers. Therefore we define the following notion. Let 1 ≤ ν ∈ R. We say a sequence As just mentioned the initial sequence m 1 , m 2 . . . , m t is valid w.r.t. n. Let us define a continuous function F : It is piecewise differentiable with right derivative ⌊lg x⌋+2. Therefore: Then we have the inequalities: Thus, we may assume ν ≥ 2. We perform induction on t. For t = 1 the statement is clear, since lg ν ≥ 1 and . , x t is valid, too; and we are done by induction. Hence, we may assume Thus, if x 1 ≤ x 2 , then the sequence x 2 , x 1 , x 3 , . . . , x t is valid, too. Thus, it is enough to consider Therefore, by induction on t and Lem. 3.4 we obtain the claim: Applying these lemmata to Eq. (2)

Partitioning
In the following T pivot (n) denotes the number of comparisons required to choose the pivot element in the worst case; and, as before, E[ T part (n) ] denotes the expected number of comparisons performed during partitioning. We have the following recurrence: If we choose the pivot at random, then we obtain by standard methods: Similarly, if we choose the pivot with the median-of-three, then we obtain: The proof of the first part of Thm. 3.1 follows from the above eqations, Thm  Thm. 3.8 is close to a well-known result in [14, Thm. 5] on Quickselect, see Cor. 3.10. Formally speaking we cannot use it directly, because we deal with QuickHeapsort, where after partitioning the recursive call is on the larger part. Because of that, and for the sake of completeness, we give a proof. Moreover, our proof is elementary and simpler than the one in [14]. The key step is Lem. 3.9. Its proof is rather standard and also can be found in App. A. Lemma 3.9 Let 0 < δ < 1 2 . If we choose the pivot as median of 2c+ 1 elements such that 2c + 1 ≤ n 2 , then we have Pr pivot ≤ n 2 − δn < (2c + 1)α c where α = 4 1 4 − δ 2 < 1.
Proof of Thm. 3.8. As an abbreviation, we let E(n) = E[ T part (n) ] be the expected number of comparisons performed during partitioning. We are going to show that for all ǫ > 0 there is some D ∈ R such that E(n) < (2 + ǫ)n + D.
In [14] it is also proved that choosing the pivot as median of O( √ n) elements is optimal for Quicksort as well as for Quickselect. This suggests that we choose the same value in QuickHeapsort; what is backed by our experiments.

Modifications of QuickHeapsort Using Extraspace
In this section we want to describe some modification of QuickHeapsort using n bits of extra storage. We introduce two bit-arrays. In one of them (the Com-pareArray) -which is actually two bits per element -we store the comparisons already done (we need two bits, because there are three possible values -right, left, unknown -we have to store). In the other one (the RedGreenArray) we store which element is red and which is green. Since the heaps have maximum size n/2, the RedGreenArray only requires n/2 bits. The CompareArray is only needed for the inner nodes of the heaps, i.e. length n/4 is sufficient. Totally this sums up to n extra bits.
For the heap construction we do not use the algorithms described in Sect. 3.1. With the CompareArray we can do better by using the algorithm of McDiarmid and Reed [15]. The heap construction works similarly to Bottom-Up-Heapsort, i.e. the array is traversed backward calling for all inner positions i the Reheap procedure on i. The Reheap procedure takes the subheap with root i and restores the heap condition, if it is violated at the position i. First, the Reheap procedure determines a special leaf using the SpecialLeaf procedure as described in Sect. 2, but without moving the elements. Then, the final position of the former root is determined going upward from the special leaf (bottom-up-phase). In the end, the elements above this final position are moved up towards the root by one position. That means that all but one element which are compared during the bottom-up-phase, stay in their places. Since in the SpecialLeaf procedure these elements have been compared with their siblings, these comparisons can be stored in the CompareArray and can be used later.
With another improvement concerning the construction of heaps with seven elements as in [3] the benefits of this array can be exploited even more.
The RedGreenArray is used during the sorting phase, only. Its functionality is straightforward: Every time a red element is inserted into the heap, the corresponding bit is set to red. The SpecialLeaf procedure can stop as soon as it reaches an element without green children. Whenever a red and a green element have to be compared, the comparison can be skipped.
g., f (n) = lg n, and let E[ T (n) ] be the expected number of comparisons by QuickHeapsort using the CompareArray with the improvement of [3] and the RedGreenArray on a fixed input array of size n. Choosing the pivot as median of f (n) randomly selected elements in time O(f (n)), we have Proof. We can analyze the savings by the two arrays separately, because the CompareArray only affects comparisons between two green elements, while the RedGreenArray only affects comparisons involving at least one red element.
First, we consider the heap construction using the CompareArray. With this array we obtain the same worst case bound as for the standard heap construction method. However, the CompareArray has the advantage that at the end of the heap construction many comparisons are stored in the array and can be reused for the extraction phase. More precisely: For every comparison except the first one made when going upward from the special leaf, one comparison is stored in the CompareArray, since for every additional comparison one element on the path defined by SpecialLeaf stays at its place. Because every pair of siblings has to be compared at one point during the heap construction or extraction, all these stored comparisons can be reused. Hence, we only have to count the comparisons in the SpecialLeaf procedure during the construction plus n 2 for the first comparison when going upward. Thus, we get an amortized bound for the comparisons during construction of 3n 2 . In [3] the notion of Fine-Heaps is introduced. A Fine Heap is a heap with the additional CompareArray such that for every node the larger child is stored in the array. Such a Fine-Heap of size m can be constructed using the above method with 2m comparisons. In [3] Carlsson, Chen and Mattsson showed that a Fine-Heap of size m actually can be constructed with only 23 12 m + O(lg 2 m) comparisons. That means we have to invest 23 12 m + O(lg 2 m) for the heap construction and at the end there are m 2 comparisons stored in the array. All these comparisons stored in the array are used later. Summing up over all heaps during an execution of QuickHeapsort, we can save another 1 12 n comparisons additionally to the comparisons saved by the CompareArray with the result of [3]. Hence, for the amortized cost of the heap construction T amort con (i.e. the number of comparisons needed to build the heap minus the number of comparisons stored in the CompareArray after the construction which all can be reused later) we have obtained: . This bound is slightly better than the average case for the heap construction with the algorithm of [15] which is 1.52n. Now, we want to count the number of comparisons we save using the Red-GreenArray. We distinguish the two cases that two red elements are compared and that a red and a green element are compared. Every position in the heap has to turn red at one point. At that time, all nodes below this position are already red. Hence, for that element we save as many comparisons as the element is above the bottom level. Summing over all levels of a heap of size m the saving results in ≈ m 4 · 1 + m 8 · 2 + · · · = m · i≥1 i2 −i−1 = m. This estimate is exact up to O(lg m)-terms. Since the expected number of heaps is O(lg n), we obtain for the overall saving the value T saveRR (n) = n + O(lg 2 n). Another place where we save comparisons with the RedGreenArray is when a red element is compared with a green element. It occurs at least one timewhen the node looses its last green child -for every inner node that we compare a red child with a green child. Hence, we save at least as many comparisons as there are inner nodes with two children, i.e. at least m 2 − 1. Since every element -except the expected O(lg n) pivot elements -is part of a heap exactly once, we save at least T saveRG (n) ≥ n 2 + O(lg n) comparisons when comparing green with red elements. In the average case the saving might be even slightly higher, since comparisons can also be saved when a node does not loose its last green child.
Summing up all our savings and using the median of f (n) ∈ ω(1) ∩ o(n) as pivot we obtain the proof of Thm. 4.1: ≤ n lg n − 0.997n + o(n).

Experimental Results and Conclusion
In Fig. 1 we present the number of comparisons of the different versions of QuickHeapsort we considered in this paper, i.e. the basic version, the improved variant of Sect. 2, and the version using bit-arrays (however, without the modification by [3]) for different values of n. We compare them with Quicksort, Ultimate Heapsort, Bottom-Up-Heapsort and MDR-Heapsort. All algorithms are implemented with median of √ n elements as pivot (for Quicksort we show additionally the data with median of 3). For the heap construction we implemented the normal algorithm due to Floyd [9] as well as the algorithm using the extra bit-array (which is the same as in MDR-Heapsort). More results with other pivot selection strategies are in Table 2 and Table 3 in App. B confirming that a sample size of √ n is optimal for pivot selection with respect to the number of comparisons and also that the o(n)-terms in Thm. 3.1 and Thm. 3.8 are not too big. In Table 1 in App. B we present actual running times of the different algorithms for n = 1000000. All the numbers, except the running times, are average values over 100 runs with random data. As our theoretical estimates predict, QuickHeapsort with bit-arrays beats all other variants including Relaxed-Weak-Heapsort (see Table 2, App. B) when implemented with median of √ n for pivot selection. It also performs 326728 ≈ 0.33 · 10 6 comparisons less than our theoretical predictions which are 10 6 · lg(10 6 ) − 0.9139 · 10 6 ≈ 19017569 comparisons. In this paper we have shown that with known techniques QuickHeapsort can be implemented with expected number of comparisons less than n lg n − 0.03n + o(n) and extra storage O(1). On the other hand, using n extra bits we can improve this to n lg n − 0.997n + o(n), i.e. we showed that QuickHeapsort can compete with the most advanced Heapsort variants. These theoretical estimates were also confirmed by our experiments. We also considered different pivot selection schemes. For any constant size sample for pivot selection, Quick-Heapsort beats Quicksort for large n, since Quicksort has a expected running time of ≈ Cn lg n with C > 1. However, when choosing the pivot as median of √ n elements (i.e. with the optimal strategy) then our experiments show that Quicksort needs less comparisons than QuickHeapsort. However, using bitarrays QuickHeapsort is the winner, again. In order to make the last statement rigorous, better theoretical bounds for Quicksort with sampling √ n elements are needed. For future work it would also be of interest to prove the optimality of √ n elements for pivot selection in QuickHeapsort, to estimate the lower order terms of the average running time of QuickHeapsort and also to find an exact average case analysis for the saving by the bit-arrays.

APPENDIX A Proofs
Proof of Lem. 3.4 Since the right derivative is monotonically increasing we have: This yields: By adding F (x) + F (y − δ) on both sides we obtain the first claim of Lem. 3.4. Note that lim ε→0 F (ε) = 0. Hence the second claim follows from the first by considering the limit δ → y.
Proof of Lem. 3.9. First note that the probability for choosing the k-th element as pivot satisfies We use the notation of falling factorial x ℓ = x · · · (x − ℓ + 1). Thus, x ℓ = x ℓ ℓ! . .
For k ≤ c we have Pr [ pivot = k ] = 0. So, let c < k ≤ n 2 − δn and let us consider an index i in the product with 0 ≤ i < c.
We have 2c c ≤ 4 c . Since 2c + 1 ≤ n 2 , we obtain: Now, we obtain the desired result.

B More Experimental Results
In Table 1 we present actual running times of the different algorithms for n = 1000000 with two different comparison functions (the numbers displayed here are averages over 10 runs with random data). One of them is the normal integer comparison, the other one first applies four times the logarithm to both operands before comparing them. Like in [8], this simulates expensive comparisons.
In Table 2 all algorithms are implemented with median of 3 and with median of √ n elements as pivot. We compare them with Quicksort implemented with the same pivot selection strategies, Ultimate Heapsort, Bottom-Up-Heapsort and MDR-Heapsort. In Table 2 we also added the values for Relaxed-Weak-Heapsort which were presented in [8]. We also compare the different pivot selection strategies on the basic Quick-Heapsort with no modifications. We test sample of sizes of one, three, approximately lg n, 4 √ n, n/ lg n, √ n, and n 3 4 for the pivot selection. In Table 3 the average number of comparisons and the standard deviations are listed. We ran the algorithms on arrays of length 10000 and one million. Table 2: QuickHeapsort and other algorithms tested on 10 6 elements (the data for Relaxed-Weak-Heapsort is taken from [8]).

Sorting algorithm
Average The displayed data is the average resp. standard deviation of 100 runs of Quick-Heapsort with the respective pivot selection strategy. These results are not very surprising: The larger the samples get, the smaller is the standard deviation. The average number of comparisons reaches its minimum with a sample size of approximately √ n elements. One notices that the difference for the average number of comparisons is relatively small, especially between the different pivot selection strategies with non-constant sample sizes. This confirms experimentally that the o(n)-terms in Thm. 3.1 and Thm. 3.8 are not too big.

C Some Words about the Worst Case Running Time
Obviously the worst case running time depends on how the pivot element is chosen. If just one random element is used as pivot we get the same quadratic worst case running time as for Quicksort. However the probability that in QuickHeapsort we run in such a "bad case" is not higher than in Quicksort, since any choice of pivot elements leading to a worst case scenario in QuickHeapsort also yields the worst case for Quicksort. If we choose the pivot element as median of approximately 2 lg n elements, we get a worst case running time of O n 2 lg n , i.e. for the worst case it makes almost no difference, if the pivot is selected as median of 2 lg n or just as one random element.
However, if we use approximately n lg n elements as sample for the pivot selection, we can get a better bound on the worst case.
Let f : N → N ≥1 be some monotonically growing function with f ∈ o(n) (e.g. f (n) = lg n). We can apply the ideas of the Median of Medians algorithm [1]: First we choose n f (n) random elements, then we group them into groups of five elements each. The median of each group can be determined with six comparisons [13, p. 215]. Now, the median of these medians can be computed using Quickselect. We assume that Quickselect is implemented with the same strategy for pivot selection. That means we get the same recurrence relations for the worst case complexity of the partitioning-phases in QuickHeapsort and for the worst case of Quickselect: T (n) = n + 6n 5f (n) + T n 5f (n) + T n − 3n 10f (n) .
This yields T (n) ≤ cnf (n) for some c large enough. Hence with this pivot selection strategy, we reach a worst case running time for QuickHeapsort of n lg n + O(nf (n)) and -if f (n) ∈ ω(1) -average running time as stated in Sect. 3. Driving this strategy to the end and choosing f (n) = 1 leads to Ultimate Heapsort (or better a slight modification of it -and Quickselect turns into the Median of Medians algorithm). Then we have T (n) = n lg n + O(n) for the worst case of QuickHeapsort. However, our bound for the average case does not hold anymore.
In order to obtain an n lg n + O(n)-bound for the worst case without loosing our bound for the average case, we can apply a simple trick: Whenever after the partitioning it turns out that the pivot does not lie in the interval { n 4 , . . . , 3n 4 } we switch to Ultimate Heapsort. This immediately yields the worst case bound of n lg n + O(n). Moreover, the proof of Thm. 3.8 can easily be changed in order to deal with this modification: Let C · n be the worst case number of comparisons for pivot selection and partitioning in Ultimate Heapsort. We can change Eq. (7) to Then, the rest of the proof is exactly the same. Hence, Thm. 3.8 and Thm. 3.1 are also valid when switching to Ultimate Heapsort in the case of a 'bad' choice of the pivot. The procedure TwoLayerMinHeap is symmetric to TwoLayerMaxHeap, so we do not present its pseudocode here.