1 #include <iostream> 2 #include <vector> 3 4 std::vector<int> g_array { 5 12, 3, 52, 65, 9, 29,16, 7, 2, 78, 63, 98, 23, 43, 1, 24, 84, 34, 94, 32 6 }; 7 void Swap(std::vector<int>& array, int i, int j) { 8 int temp = array[j]; 9 array[j] = array[i]; 10 array[i] = temp; 11 } 12 void ShowArray(std::vector<int>& array) { 13 for (int i = 0; i < array.size(); ++i) { 14 std::cout << array[i] << " "; 15 } 16 std::cout << " "; 17 } 18 19 // ----------------比较排序----------------- 20 // 冒泡排序:交换,时间复杂度O(n)- O(n2),空间复杂度O(1) 21 void BubbleSort(std::vector<int>& array); 22 // 快速排序:分治法+交换+双重游标,时间复杂度O(nlogn) - O(n2),空间复杂度O(nlogn).递归算法每次都要存储栈信息,因此为nlogn 23 void QuickSort(std::vector<int>& array, int begin, int end); 24 // 插入排序:有序子序列 + 插入位置 + 连续数量移动,时间复杂度O(n) - O(n2),空间复杂度O(1) 25 void InsertionSort1(std::vector<int>& array); // 找到位置后移动 26 void InsertionSort2(std::vector<int>& array); // 比较相邻元素,然后交互 27 // shell 排序:宏观调控 + 增量子序列 + 增量减少至1。时间复杂度O(n1.3) - O(n2),空间复杂度O(1)。shell增量的选择是个数学难题,一般采用length/作为步长 28 void ShellSort1(std::vector<int>& array); // 找到位置后移动 29 void ShellSort2(std::vector<int>& array); // 比较相邻元素,然后交互 30 // 选择排序.O(n2),空间复杂度O(1).找到最小元素,放到队列头,队列头有序。以此类推 31 void SelectionSort(std::vector<int>& array); 32 // 堆排序. 时间复杂度O(nlogn),空间复杂度O(nlogn) 33 void HeapSort(std::vector<int>& array); 34 // 归并排序.时间复杂度O(nlogn),空间复杂度O(nlogn) 35 void MergeSort(std::vector<int>& array, int begin, int end); 36 // -----------------非比较排序---------------- 37 // 计数排序.时间复杂度O(n+k),空间复杂度O(n+k),k是整数取值范围.快过任何比较排序算法,但是对空间要求较高,适用于有限小范围的区域 38 void CountingSort(std::vector<int>& array, int max = 100); 39 // 桶排序,是计数排序的升级版本。时间复杂度O(n+k) - O(n2),空间复杂度O(n+k),k是整数取值范围.快过任何比较排序算法,但是对空间要求较高,适用于有限小范围的区域 40 // 计数排序申请的空间比较大,如果分散不均匀,很多空间未访问,会造成浪费。桶排序取出最大值和最小值的差值,划分成若干个 连续+范围递增 的数组,每个数组进行内部排序 41 void BucketSort(std::vector<int>& array); 42 // 基数排序.时间复杂度O(n*k),空间复杂度O(n+k) 43 void RadixSort(std::vector<int>& array); 44 45 int main() { 46 // BubbleSort(g_array); 47 // QuickSort(g_array, 0, g_array.size() - 1); 48 // InsertionSort2(g_array); 49 // ShellSort2(g_array); 50 // SelectionSort(g_array); 51 // HeapSort(g_array); 52 // MergeSort(g_array, 0, g_array.size() - 1); 53 // CountingSort(g_array); 54 // BucketSort(g_array); 55 RadixSort(g_array); 56 ShowArray(g_array); 57 return 0; 58 } 59 60 void BubbleSort(std::vector<int>& array) { 61 const size_t sz = array.size(); 62 if (sz <= 1) { 63 return; 64 } 65 for (int i = 0; i < sz; ++i) { 66 for (int j = 0; j < sz - i - 1; ++j) { 67 if (array[j] > array[j + 1]) { 68 Swap(array, j, j + 1); 69 } 70 } 71 } 72 } 73 74 void QuickSort(std::vector<int>& nums, int l ,int r) { 75 if (l < r) { 76 const int target = nums[l]; 77 int b = l + 1; 78 int e = r; 79 while (b < e) 80 { 81 if (nums[b] >= target && nums[e] < target) { 82 Swap(nums, b, e); 83 } 84 if (nums[b] < target) { 85 b++; 86 } 87 if (nums[e] >= target) { 88 e--; 89 } 90 } 91 if (nums[l] > nums[b]) { 92 Swap(nums, b, l); 93 } 94 QuickSort(nums, l, b - 1); 95 QuickSort(nums, b, r); 96 } 97 } 98 99 void InsertionSort1(std::vector<int> &array) { 100 const size_t sz = array.size(); 101 if (sz <= 1) { 102 return; 103 } 104 for (int i = 1; i < sz; ++i) { 105 const int target = array[i]; 106 int j = i; 107 for (; j > 0; --j) { 108 if (array[j - 1] <= target) { 109 break; 110 } 111 } 112 for (int k = i; k > j; --k) { 113 array[k] = array[k - 1]; 114 } 115 array[j] = target; 116 } 117 } 118 119 void InsertionSort2(std::vector<int> &array) { 120 const size_t sz = array.size(); 121 if (sz <= 1) { 122 return; 123 } 124 for (int i = 1; i < sz; ++i) { 125 const int target = array[i]; 126 int j = i; 127 for (; j > 0 && array[j] < array[j - 1]; --j) { 128 Swap(array, j, j -1); 129 } 130 array[j] = target; 131 } 132 } 133 134 void ShellSort1(std::vector<int> &array) { 135 const size_t sz = array.size(); 136 if (sz <= 1) { 137 return; 138 } 139 for (int gap = sz/2; gap > 0; gap = gap/2) { 140 for (int i = 0; i < gap; ++i) { 141 // 对每组增量进行插入排序 142 for (int j = i + gap; j < sz; j += gap) { 143 const int target = array[j]; 144 int k = j; 145 for (; k > 0; k -= gap) { 146 if (array[k - gap] < target) { 147 break; 148 } 149 } 150 for (int l = j; l > k; l -= gap) { 151 array[l] = array[l - gap]; 152 } 153 array[k] = target; 154 } 155 } 156 } 157 } 158 159 void ShellSort2(std::vector<int> &array) { 160 const size_t sz = array.size(); 161 if (sz <= 1) { 162 return; 163 } 164 for (int gap = sz/2; gap > 0; gap = gap/2) { 165 for (int i = gap; i < sz; ++i) { 166 const int target = array[i]; 167 int j = i; 168 for (; j >= gap && array[j] < array[j - gap]; j = j - gap) { 169 Swap(array, j, j - gap); 170 } 171 array[j] = target; 172 } 173 } 174 } 175 176 void SelectionSort(std::vector<int> &array) { 177 const size_t sz = array.size(); 178 if (sz <= 1) { 179 return; 180 } 181 for (int i = 0; i < sz; ++i) { 182 int min = array[i]; 183 int index = i; 184 for (int j = i; j < sz; ++j) { 185 if (array[j] < min) { 186 min = array[j]; 187 index = j; 188 } 189 } 190 Swap(array, index, i); 191 } 192 } 193 194 void AdjustHeap(std::vector<int> &array, int parent, int sz) { 195 if (sz <= 1) { 196 return; 197 } 198 const int left = parent*2 + 1; 199 if (left >= sz) { 200 return; 201 } else { 202 const int right = parent*2 + 2; 203 if (right >= sz) { 204 if (array[parent] < array[left]) { 205 Swap(array, parent, left); 206 AdjustHeap(array, left, sz); 207 } 208 } else { 209 int max = array[right] < array[left] ? left : right; 210 if (array[parent] < array[max]) { 211 Swap(array, parent, max); 212 AdjustHeap(array, max, sz); 213 } 214 } 215 } 216 } 217 218 void HeapSort(std::vector<int> &array) { 219 const size_t sz = array.size(); 220 if (sz <= 1) { 221 return; 222 } 223 // 构建大顶堆 224 for (int i = sz - 1; i > 0; i = i - 2) { 225 const int parent = i/2; 226 AdjustHeap(array, parent, sz); 227 } 228 // 交换最大元素到末尾 229 for (int j = 1; j <= sz; ++j) { 230 Swap(array, 0, sz - j); 231 AdjustHeap(array, 0, sz - j); 232 } 233 } 234 235 std::vector<int> temp; 236 void MergeSort(std::vector<int> &array, int begin, int end) { 237 const size_t sz = end - begin + 1; 238 if (sz <= 1) { 239 return; 240 } 241 int mid = (begin + end)/2; 242 MergeSort(array, begin, mid); 243 MergeSort(array, mid + 1, end); 244 245 int left = begin; 246 int right = mid + 1; 247 248 temp.resize(sz); 249 for (int i = begin; i <= end; ++i) { 250 int min; 251 if (left > mid) { 252 min = right++; 253 } else if (right > end) { 254 min = left++; 255 } else if (array[left] < array[right]) { 256 min = left++; 257 } else { 258 min = right++; 259 } 260 temp.push_back(array[min]); 261 } 262 for (int i = begin; i <= end; ++i) { 263 array[i] = temp[i - begin]; 264 } 265 } 266 267 void CountingSort(std::vector<int> &array, int max) { 268 const size_t sz = array.size(); 269 if (sz <= 1) { 270 return; 271 } 272 std::vector<int> count(max, 0); 273 for (int i = 0; i < sz; ++i) { 274 count[array[i]]++; 275 } 276 array.clear(); 277 array.reserve(sz); 278 for (int j = 0; j < max; ++j) { 279 while (count[j]-- > 0) { 280 array.push_back(j); 281 } 282 } 283 } 284 285 void BucketSort(std::vector<int> &array) { 286 const size_t sz = array.size(); 287 if (sz <= 1) { 288 return; 289 } 290 int max = std::numeric_limits<int>::min(); 291 int min = std::numeric_limits<int>::max(); 292 for (int i = 0; i < sz; ++i) { 293 if (array[i] > max) { 294 max = array[i]; 295 } 296 if (array[i] < min) { 297 min = array[i]; 298 } 299 } 300 const int bucketCount = 1; 301 std::vector<std::vector<int>> buckets; 302 buckets.resize(bucketCount); 303 const int bucketRangeIncrease = (max - min)/bucketCount + 1; // 这里+1很重要 304 for (int j = 0; j < sz; ++j) { 305 // 采用相对法,保证(array[j] - min)一定>=0。如果带排序内有负数,则下标计算出来是负值 306 buckets[(array[j] - min)/bucketRangeIncrease].push_back(array[j]); 307 } 308 array.clear(); 309 for (int k = 0; k < bucketCount; ++k) { 310 if (buckets[k].empty()) { 311 continue; 312 } 313 InsertionSort1(buckets[k]); 314 for (int i = 0; i < buckets[k].size(); ++i) { 315 array.push_back(buckets[k][i]); 316 } 317 } 318 } 319 320 void RadixSort(std::vector<int> &array) { 321 const size_t sz = array.size(); 322 if (sz <= 1) { 323 return; 324 } 325 int max = std::numeric_limits<int>::min(); 326 for (int i = 0; i < sz; ++i) { 327 if (max < array[i]) { 328 max = array[i]; 329 } 330 } 331 int count = 1; 332 int radix = 1; 333 while (max / radix > 10) { 334 radix *= 10; 335 count++; 336 } 337 std::vector<std::vector<int>> buckets; 338 for (int j = 1; j <= count; ++j) { 339 buckets.clear(); 340 buckets.resize(10); // 0 - 9 341 radix = 1; 342 for (int k = 1; k < j; ++k) { 343 radix *= 10; 344 } 345 for (int i = 0; i < sz; ++i) { 346 int index = (array[i] / radix) % 10; 347 buckets[index].push_back(array[i]); 348 } 349 array.clear(); 350 array.reserve(sz); 351 for (int l = 0; l < 10; ++l) { 352 for (int i = 0; i < buckets[l].size(); ++i) { 353 array.push_back(buckets[l][i]); 354 } 355 } 356 } 357 }