int Partition1(int*a,int left,int right) {
int keyi = left;
while (left < right) {
while (left < right && a[right] >= a[keyi])
right--;
while (left < right && a[left] <= a[keyi])
left++;
swap(&a[left],&a[right]);
}
swap(&a[keyi],&a[left]);
return left;
}
int Partition2(int* a, int left, int right) {
int key = a[left];
while (left < right) {
while (left < right && a[right] >= key)
right--;
a[left] = a[right];
while (left < right && a[left] <= key)
left++;
a[right]=a[left];
}
a[left] = key;
return left;
}
int Partition3(int* a, int left, int right) {
int keyi = left;
int pre = left, cur = left + 1;
while (cur <= right) {
if (a[cur] < a[keyi]) {
pre++;
swap(&a[pre],&a[cur]);
}
cur++;
}
swap(&a[pre], &a[keyi]);
return pre;
}
举个例子帮助大家理解一下双指针法
本质和树的先序遍历的非递归写法一样
void QuickSortNonR(int* a, int left, int right) {
ST st;
StackInit(&st);
//存放区间
StackPush(&st, right);
StackPush(&st, left);
while (!StackEmpty(&st)) {
int left = StackTop(&st);
StackPop(&st);
int right = StackTop(&st);
StackPop(&st);
int mid = PartSort1(a, left, right);
if (mid - 1 > left) {//保证区间合法
StackPush(&st, mid - 1);
StackPush(&st, left);
}
if (mid + 1 < right) {//保证区间合法
StackPush(&st, right);
StackPush(&st, mid+1);
}
}
StackDestroy(&st);
}
//三路划分
void QuickSort_T(int* a, int left, int right) {
if (left >= right)//保证区间合法
return;
int L = left, R = right;
int key = a[left];
int cur = left + 1;
while (cur <= right) {
if (a[cur] < key) {
swap(&a[cur], &a[L]);
L++;
cur++;
}else if (a[cur] == key) {
cur++;
}else {
swap(&a[R], &a[cur]);
R--;
}
}
QuickSort_T(a, left, L - 1);
QuickSort_T(a, R + 1, right);
}
举个例子
void CountSort(int* a, int n) {
int min = a[0], max = a[0];
for (int i = 1; i < n; i++) {
if (a[i] < min)min = a[i];
if (a[i] > max)max = a[i];
}
int range = max - min + 1;
int* count_a = (int*)malloc(sizeof(int) * range);
memset(count_a, 0, sizeof(int) * range);
for (int i = 0; i < n; i++) {
count_a[a[i] - min]++;
}
for (int i = 0,k = 0; i < range; i++) {
while(count_a[i]--) {
a[k++] = i + min;
}
}
}
void _MergeSort(int* a, int left, int right, int* tmp) {
if (left >= right)
return;
//小区间优化
if (right - left + 1 < 10) {
InsertSort(a + left, right - left + 1);
return;
}
int mid = left + (right - left) / 2;
_MergeSort(a, left, mid, tmp);
_MergeSort(a, mid+1,right, tmp);
//这里只能分成[left,mid][mid+1,right](因为mid=(left+right)/2)
//如果分成[left,mid-1][mid,right]
//当left和right相差为1时,mid=left
//那么dfs(left,right)
//=>dfs(left,mid-1) dfs(mid,right)
//<=>dfs(left,left-1) dfs(left,right)
//<=>return dfs(left,mid-1) dfs(mid,right)
//很显然,死递归了,问题就是在于dfs(left,right)一直在不停的重复递归
int L1 = left, R1 = mid;
int L2 = mid + 1, R2 = right;
int k = 0;
while (L1 <= R1 && L2 <= R2) {
if (a[L1] < a[L2]) {
tmp[k++] = a[L1++];
}else{
tmp[k++] = a[L2++];
}
}
while (L1 <= R1)tmp[k++] = a[L1++];
while (L2 <= R2)tmp[k++] = a[L2++];
memcpy(a + left, tmp, sizeof(int) * k);
}
//归并
void MergeSort(int* a, int n) {
int* tmp = (int*)malloc(sizeof(int) * n);
_MergeSort(a, 0, n - 1, tmp);
free(tmp);
}