快排摸板
void quickSort(int nums[], int l, int r)
{
if(l >= r) return;
int x = nums[l];
int lp = l-1, rp = r+1; // 定义左右两指针
while(lp < rp)
{
do lp++; while (q[lp] < x);
do rp--; while (q[rp] > x);
if (lp < rp) swap(q[lp], q[rp]);
}
//写法一:
quickSort(nums, l, rp);
quickSort(nums, rp+1, r);
/**
写法二:
quickSort(nums, r, lp-1);
quickSort(nums, lp, r);
**/
}
注意:递归的区间选取有个小细节,若选择写法二,则x不能选择区间左端点,为什么会出现这种情况呢?以下考虑一种极端情况:3,6,4,7,9,8 ;此时左指针不会发生移动,当递归调用时,仍得到整个区间,造成死循环。同理采用写法一时,x不能取到区间右端点。
对于一次划分后lp和rp的位置: 若选取的划分值为奇数个,则lp与rp重合,若选取的划分值为奇数个值为偶数个,则rp位于lp前一个位置。
例题:传送门
题解:
#include <iostream>
#include <cstdlib>
#include <ctime>
using namespace std;
const int N = 100010;
int nums[N], n;
void quickSort(int q[], int l, int r)
{
if(l >= r) return;
int x = q[rand()%(r-l+1)+l]; //防止特殊数据,随机选择区间内的点
int lp = l-1, rp = r+1;
while(lp < rp)
{
do lp++; while (q[lp] < x);
do rp--; while (q[rp] > x);
if (lp < rp) swap(q[lp], q[rp]);
}
quickSort(nums, l, rp);
quickSort(nums, rp+1, r);
}
int main ()
{
srand((unsigned int)time(NULL));
cin >> n;
for (int i = 0; i < n; i++) cin >> nums[i];
quickSort(nums, 0, n-1);
for(int i = 0; i < n; i++)
{
cout << nums[i];
if(i == n-1) cout << endl;
else cout << " ";
}
return 0;
}
归并模板
void mergeSort(int q[], int l, int r)
{
if (l >= r) return;
int mid = (l + r) >> 1;
mergeSort(q, l, mid), mergeSort(q, mid+1, r);
// 利用临时数组temp进行合并
int k = 0, f = l, s = mid + 1;// f为左区间的指针,s为右区间的指针
while (f <= mid && s <= r)
{
if(q[f] <= q[s]) temp[k++] = q[f++];
else temp[k++] = q[s++];
}
while (f <= mid) temp[k++] = q[f++];
while (s <= r) temp[k++] = q[s++];
for(int i = l, j = 0; i <= r; i++, j++) q[i] = temp[j];
}
例题:传送门
题解:
#include <iostream>
using namespace std;
const int N = 100010;
int nums[N], temp[N], n;
void mergeSort(int q[], int l, int r)
{
if (l >= r) return;
int mid = (l + r) >> 1;
mergeSort(q, l, mid), mergeSort(q, mid+1, r);
int k = 0, f = l, s = mid + 1;
while (f <= mid && s <= r)
{
if(q[f] <= q[s]) temp[k++] = q[f++];
else temp[k++] = q[s++];
}
while (f <= mid) temp[k++] = q[f++];
while (s <= r) temp[k++] = q[s++];
for(int i = l, j = 0; i <= r; i++, j++) q[i] = temp[j];
}
int main()
{
cin >> n;
for (int i = 0; i < n; i++) cin >> nums[i];
mergeSort(nums, 0, n-1);
for (int i = 0; i < n; i++) cout << nums[i] << " ";
return 0;
}