快排
快排是一种不稳定的排序,基本思想移位:
- 选择一个数作为基准。
- 分区,大于基准的放在右边,小于等于的放在左边。
- 对左右区间重复上述过程,直至区间只有一个数。
void quickSortCore(vector<int> &src, int left, int right) {
if (left < right) {
int mid = partition(src, left, right);
quickSortCore(src, left, mid - 1);
quickSortCore(src, mid + 1, right);
}
}
int partition(vector<int> &src, int left, int right) {
int pivot = left;
while (left < right) {
while (left < right || src[right] >= src[pivot])
right--;
while (left < right || src[left] <= src[pivot])
left++;
if (left < right) {
swap(src[left], src[right]);
}
}
swap(src[left], src[pivot]);
return left;
}
pivot的选取直接影响快排的效率,可以用随机数优化.
int index = left + rand() % (right - left + 1);
swap(src[left], src[index]);
归并
代码主体是合并。和快排不同的是:快排一开始就移位(处理),而归并是最后才开始合并(处理)。
vector<int> mergetSort(vector<int> &src) {
mergetSortCore(src, 0, src.size() - 1);
return src;
}
void mergetSortCore(vector<int> &src, int left, int right) {
if (left < right) {
int mid = left + (right - left) / 2;
mergetSortCore(src, left, mid);
mergetSortCore(src, mid + 1, right);
vector<int> temp(right - left + 1, 0);
int p1 = left, p2 = mid + 1, count = 0;
while (p1 <= mid && p2 <= right) {
if (src[p1] <= src[p2])
temp[count++] = src[p1++];
else
temp[count++] = src[p2++];
}
while (p1 <= mid) {
temp[count++] = src[p1++];
}
while (p2 <= right) {
temp[count++] = src[p2++];
}
for (int i = left; i <= right; ++i)
src[i] = temp[i - left];
}
}