commit e15d51510048927f172f1bf1f27ede65907d940d Author: Leon Bottou Date: Mon Apr 8 22:25:55 2019 -0400 bug 299 fixed diff --git a/libdjvu/GContainer.h b/libdjvu/GContainer.h index 96b067c..0140211 100644 --- a/libdjvu/GContainer.h +++ b/libdjvu/GContainer.h @@ -550,52 +550,61 @@ public: template void GArrayTemplate::sort(int lo, int hi) { - if (hi <= lo) - return; - if (hi > hibound || lo hibound || lo=lo) && !(data[j]<=tmp)) - data[j+1] = data[j]; - data[j+1] = tmp; + for (int i=lo+1; i<=hi; i++) + { + int j = i; + TYPE tmp = data[i]; + while ((--j>=lo) && !(data[j]<=tmp)) + data[j+1] = data[j]; + data[j+1] = tmp; + } + return; } - return; - } - // -- determine suitable quick-sort pivot - TYPE tmp = data[lo]; - TYPE pivot = data[(lo+hi)/2]; - if (pivot <= tmp) - { tmp = pivot; pivot=data[lo]; } - if (data[hi] <= tmp) - { pivot = tmp; } - else if (data[hi] <= pivot) - { pivot = data[hi]; } - // -- partition set - int h = hi; - int l = lo; - while (l < h) - { - while (! (pivot <= data[l])) l++; - while (! (data[h] <= pivot)) h--; - if (l < h) + // -- determine median-of-three pivot + TYPE tmp = data[lo]; + TYPE pivot = data[(lo+hi)/2]; + if (pivot <= tmp) + { tmp = pivot; pivot=data[lo]; } + if (data[hi] <= tmp) + { pivot = tmp; } + else if (data[hi] <= pivot) + { pivot = data[hi]; } + // -- partition set + int h = hi; + int l = lo; + while (l < h) { - tmp = data[l]; - data[l] = data[h]; - data[h] = tmp; - l = l+1; - h = h-1; + while (! (pivot <= data[l])) l++; + while (! (data[h] <= pivot)) h--; + if (l < h) + { + tmp = data[l]; + data[l] = data[h]; + data[h] = tmp; + l = l+1; + h = h-1; + } + } + // -- recurse, small partition first + // tail-recursion elimination + if (h - lo <= hi - l) { + sort(lo,h); + lo = l; // sort(l,hi) + } else { + sort(l,hi); + hi = h; // sort(lo,h) } } - // -- recursively restart - sort(lo, h); - sort(l, hi); } template inline TYPE&