SparseLibrary  Version 1.6.0
custom_quicksort.hpp
1 /*
2  * Copyright (c) 2007-2014, A. N. Yzelman, Utrecht University 2007-2011;
3  * KU Leuven 2011-2014.
4  * R. H. Bisseling, Utrecht University 2007-2014.
5  *
6  * This file is part of the Sparse Library.
7  *
8  * This library was developed under supervision of Prof. dr. Rob H. Bisseling at
9  * Utrecht University, from 2007 until 2011. From 2011-2014, development continued
10  * at KU Leuven, where Prof. dr. Dirk Roose contributed significantly to the ideas
11  * behind the newer parts of the library code.
12  *
13  * The Sparse Library is free software: you can redistribute it and/or modify
14  * it under the terms of the GNU General Public License as published by the
15  * Free Software Foundation, either version 3 of the License, or (at your
16  * option) any later version.
17  *
18  * The Sparse Library is distributed in the hope that it will be useful, but
19  * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
20  * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
21  * for more details.
22  *
23  * You should have received a copy of the GNU General Public License along
24  * with the Sparse Library. If not, see <http://www.gnu.org/licenses/>.
25  */
26 
27 
28 /*
29  * File created by:
30  * A. N. Yzelman, Dept. of Computer Science, KU Leuven, 2012.
31  */
32 
33 #ifndef _H_CUSTOM_QUICKSORT
34 #define _H_CUSTOM_QUICKSORT
35 
36 #include <vector>
37 #include <algorithm>
38 
50 template< typename KeyType >
51 size_t custom_quicksort_getpivot( const std::vector< KeyType > &key, const size_t left, const size_t right ) {
52  size_t ret = right - left; //overflow-safe (as opposed to (right+left)/2)
53  ret /= 2;
54  ret += left;
55  return ret;
56 }
57 
70 template< typename KeyType, typename DataArrayType >
71 size_t custom_quicksort_inner( std::vector< KeyType > &key, DataArrayType &data,
72  const size_t left, const size_t right, const size_t pivot ) {
73 
74  //move pivot to end
75  std::swap( key [ pivot ], key [ right-1 ] );
76 
77  //data array mirrors every swap of the key array
78  std::swap( data[ pivot ], data[ right-1 ] );
79 
80  //remember pivot value
81  const BigInt pivotValue = key[ right-1 ];
82 
83  //screen from left to right
84  size_t curIndex = left;
85  for( size_t i = left; i < (right-1); ++i ) {
86 
87  //compare key to pivot value
88  if( key[ i ] < pivotValue ) {
89  //swap small entry to the left of the range
90  if( i != curIndex ) {
91  std::swap( key [ i ], key [ curIndex ] );
92  std::swap( data[ i ], data[ curIndex ] );
93  }
94  //increment bound
95  curIndex++;
96  }
97  }
98 
99  //move pivot value back to the middle
100  std::swap( key [ curIndex ], key [ right-1 ] );
101  std::swap( data[ curIndex ], data[ right-1 ] );
102 
103  //return new pivot position
104  return curIndex;
105 }
106 
117 template< typename KeyType, typename DataArrayType >
118 void custom_quicksort_outer( std::vector< KeyType > &key, DataArrayType &data, size_t left, size_t right ) {
119  //determine pivot value
120  const size_t pivot = custom_quicksort_getpivot( key, left, right );
121 
122  //perform inner-loop (swap-based sorting)
123  const size_t newPivotIndex = custom_quicksort_inner< KeyType, DataArrayType >( key, data, left, right, pivot );
124 
125  //recurse
126  if( newPivotIndex > left + 1 )
127  custom_quicksort_outer< KeyType, DataArrayType >( key, data, left, newPivotIndex );
128  if( newPivotIndex + 1 < right )
129  custom_quicksort_outer< KeyType, DataArrayType >( key, data, newPivotIndex + 1, right );
130 }
131 
140 template< typename KeyType, typename DataType >
141 void custom_quicksort( std::vector< KeyType > &key, std::vector< DataType > &data, size_t left, size_t right ) {
142  const bool implicit = sizeof( DataType ) > 2 * sizeof( size_t );
143 
144  //check bounds
145  if( right <= left )
146  return;
147 
148  //use a permutation array if the normal data type is too large
149  if( implicit ) {
150 
151  //allocate permutation array
152  size_t *permutation = new size_t[ right - left ];
153 
154  //initialise permutation array
155  for( size_t i = left; i < right; ++i )
156  permutation[ i ] = i;
157 
158  //perform quicksort using permutation array as the linked array
159  custom_quicksort_outer< KeyType, size_t* >( key, permutation, left, right );
160 
161  //perform permutation on the actual data array
162  std::vector< DataType > temp;
163 
164  //first create temporary array
165  for( size_t i = left; i < right; ++i )
166  temp.push_back( data[ permutation[ i ] ] );
167 
168  //copy back
169  for( size_t i = left; i < right; ++i )
170  data[ i ] = temp[ i - left ];
171 
172  //free permutation array
173  delete [] permutation;
174 
175  //free temporary array
176  temp.clear();
177 
178  } else {
179 
180  //otherwise do a direct linked quicksort
181  custom_quicksort_outer< KeyType, std::vector< DataType > >( key, data, left, right );
182  }
183 }
184 
185 #endif
186 
A 128-bit integer, with overloaded comparison operators.
Definition: BigInt.hpp:38