排序(三) 选择排序
一、选择排序
原理:
选择排序很简单,他的步骤如下:
1.从左至右遍历,找到最小(大)的元素,然后与第一个元素交换。
2.从剩余未排序元素中继续寻找最小(大)元素,然后与第二个元素进行交换。
3.以此类推,直到所有元素均排序完毕。
之所以称之为选择排序,是因为每一次遍历未排序的序列我们总是从中选择出最小的元素。
void SelectSort(vector<int>& Vector) { assert(Vector.size()); for (int i = 0; i < Vector.size() - 1; ++i) { int index = i; for (int j = index + 1; j < Vector.size(); ++j) { if (Vector[j] < Vector[index]) index = j; } swap(Vector[i], Vector[index]); } }
分析:
1.选择排序需要花费 (N – 1) + (N – 2) + … + 1 + 0 = N(N- 1) / 2 ~ N2/2次比较 和 N-1次交换操作。
2.对初始数据不敏感,不管初始的数据有没有排好序,都需要经历N2/2次比较,这对于一些原本排好序,或者近似排好序的序列来说并不具有优势。在最好的情况下,即所有的排好序,需要0次交换,最差的情况,倒序,需要N-1次交换。
3.数据交换的次数较少,如果某个元素位于正确的最终位置上,则它不会被移动。在最差情况下也只需要进行N-1次数据交换,在所有的完全依靠交换去移动元素的排序方法中,选择排序属于比较好的一种。
二、堆排序:
template<class T> void _AdjustDown(T* arr, size_t size, size_t index) { size_t child = index * 2 + 1; while (child < size) { if (child + 1 < size && arr[child + 1] > arr[child]) { ++child; } if (arr[child]>arr[index]) { swap(arr[child], arr[index]); index = child; child = child * 2 + 1; } else { break; } } } template<class T> T* HeapSort(T* arr, size_t size) { assert(arr); for (int i = (size - 2) / 2; i >= 0; --i) { _AdjustDown(arr, size, i); } while (size > 1) { swap(arr[0], arr[size - 1]); --size; _AdjustDown(arr, size, 0); return arr; } }