home *** CD-ROM | disk | FTP | other *** search
- //===================================================================
- // sort.hpp
- //
- // Version 1.1
- //
- // Written by:
- // Brent Worden
- // WordenWare
- // email: Brent@Worden.org
- //
- // Copyright (c) 1998-1999 WordenWare
- //
- // Created: August 28, 1998
- // Revised: April 10, 1999
- //===================================================================
-
- #ifndef _SORT_HPP_
- #define _SORT_HPP_
-
- #include "utility.hpp"
- #include "descript.hpp"
-
- NUM_BEGIN
-
- static const int MAX_QSORT = 10;
-
- template<class Iter>
- inline void isort(Iter first, Iter last)
- //-------------------------------------------------------------------
- // Sorts the elements of [first, last) into ascending order using
- // insertion.
- //-------------------------------------------------------------------
- {
- isort(first, last, valueType(first));
- }
-
- template<class Iter, class T>
- void isort(Iter first, Iter last, T* type)
- //-------------------------------------------------------------------
- // Sorts the elements of [first, last) into ascending order using
- // insertion.
- //-------------------------------------------------------------------
- {
- T value;
- Iter iter;
- Iter curr;
-
- for(iter = first + 1; iter != last; ++iter){
- value = *iter;
- curr = iter - 1;
- while(curr >= first && *curr > value){
- *(curr + 1) = *curr;
- curr--;
- }
- *(curr + 1) = value;
- }
- };
-
- template<class Iter1, class Iter2>
- inline void isort2(Iter1 first1, Iter1 last1, Iter2 first2)
- //-------------------------------------------------------------------
- // Sorts the elements of [first, last) into ascending numerical order
- // using insertion while making the corresponding rearrangement of
- // the elements of [first2, first2 + (last1 - first1) ).
- //-------------------------------------------------------------------
- {
- isort2(first1, last1, first2, valueType(first1), valueType(first2));
- }
-
- template<class Iter1, class Iter2, class T1, class T2>
- void isort2(Iter1 first1, Iter1 last1, Iter2 first2, T1* type1, T2* type2)
- {
- T1 value1;
- T2 value2;
- Iter1 iter1;
- Iter1 curr1;
- Iter2 iter2;
- Iter2 curr2;
-
- for(iter1 = first1 + 1, iter2 = first2 + 1; iter1 != last1; ++iter1, ++iter2){
- value1 = *iter1;
- value2 = *iter2;
- curr1 = iter1 - 1;
- curr2 = iter2 - 1;
- while(curr1 >= first1 && *curr1 > value1){
- *(curr1 + 1) = *curr1;
- curr1--;
- *(curr2 + 1) = *curr2;
- curr2--;
- }
- *(curr1 + 1) = value1;
- *(curr2 + 1) = value2;
- }
- };
-
- template<class Iter>
- void qsort(Iter first, Iter last)
- //-------------------------------------------------------------------
- // Sorts the elements of [first, last) into ascending numerical order
- // using the Quicksort.
- //-------------------------------------------------------------------
- {
- Iter loSwap;
- Iter hiSwap;
-
- if(length(first, last) > MAX_QSORT){
- loSwap = first + 1;
- hiSwap = last - 1;
- do {
- while(loSwap <= hiSwap && *loSwap <= *first){
- ++loSwap;
- }
- while(*hiSwap > *first){
- --hiSwap;
- }
- if(loSwap < hiSwap){
- std::iter_swap(loSwap, hiSwap);
- }
- } while(loSwap < hiSwap);
- std::iter_swap(first, hiSwap);
- if(first < hiSwap - 1){
- qsort(first, hiSwap);
- }
- if(hiSwap + 2 < last){
- qsort(hiSwap + 1, last);
- }
- } else {
- isort(first, last);
- }
- };
-
- template<class Iter1, class Iter2>
- void qsort2(Iter1 first1, Iter1 last1, Iter2 first2)
- //-------------------------------------------------------------------
- // Sorts the elements of [first, last) into ascending numerical order
- // using the Quicksort while making the corresponding rearrangement
- // of the elements of [first2, first2 + (last1 - first1) ).
- //-------------------------------------------------------------------
- {
- Iter1 loSwap, hiSwap;
- Iter2 lo2, hi2;
-
- if(length(first1, last1) > MAX_QSORT){
- loSwap = first1 + 1;
- hiSwap = last1 - 1;
- lo2 = first2 + 1;
- hi2 = first2 + (last1 - first1) - 1;
- do {
- while(loSwap <= hiSwap && *loSwap <= *first1){
- ++loSwap;
- ++lo2;
- }
- while(*hiSwap > *first1){
- --hiSwap;
- --hi2;
- }
- if(loSwap < hiSwap){
- std::iter_swap(loSwap, hiSwap);
- std::iter_swap(lo2, hi2);
- }
- } while(loSwap < hiSwap);
-
- std::iter_swap(first1, hiSwap);
- std::iter_swap(first2, hi2);
- if(first1 < hiSwap - 1){
- qsort2(first1, hiSwap, first2);
- }
- if(hiSwap + 2 < last1){
- qsort2(hiSwap + 1, last1, hi2 + 1);
- }
- } else {
- isort2(first1, last1, first2);
- }
- };
-
- template<class Iter1, class Iter2>
- void qsort2key(Iter1 first1, Iter1 last1, Iter2 first2)
- //-------------------------------------------------------------------
- // Sorts the element of [first1, last1) and [first2, first2 + (last1
- // - first1) ) into ascending order using [first1, last1) as the
- // primary key and [first2, first2 + (last1 - first1) ) as the
- // secondary key.
- //-------------------------------------------------------------------
- {
- Iter1 key;
- Iter2 lo, hi;
-
- qsort2(first1, last1, first2);
-
- hi = first2;
- while(first1 < last1){
- key = first1;
- lo = hi;
- while(first1 < last1 && *first1 == *key){
- ++first1;
- ++hi;
- }
- if(hi - lo > 0){
- qsort(lo, hi);
- }
- }
- };
-
- NUM_END
-
- #endif
-
- //===================================================================
- // Revision History
- //
- // Version 1.0 - 08/28/1998 - New.
- // Version 1.1 - 04/10/1999 - Added Numerics namespace.
- // Added isort1 and isort2.
- // Applied isort1 and isort2 to small
- // groups in qsort1 and qsort2.
- //===================================================================
-
-