c++实现十大经典排序算法

  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 }
原文地址:https://www.cnblogs.com/hgwang/p/15155507.html