归并排序
归并排序注重考察我们的递归分治思想,虽然做了很多递归分治思想的题,突然让我写归并,还是不知该怎么写。
void dealMergeSort(int *arr, int *tmp, int start, int end)
{
if (start >= end)
return;
int mid = (start + end) / 2;
dealMergeSort(arr, tmp, start, mid);
dealMergeSort(arr, tmp, mid+1, end);
int a = start;
int b = mid + 1;
int c = a;
for (; a <= mid&&b <= end; c++)
{
if (arr[a] < arr[b])
{
tmp[c] = arr[a];
a++;
}
else
{
tmp[c] = arr[b];
b++;
}
}
for (; a <= mid; a++, c++)
tmp[c] = arr[a];
for (; b <= end; b++, c++)
tmp[c] = arr[b];
for (int i = start; i <= end; i++)
arr[i] = tmp[i];
}
快速排序
快排很简单,但今天看见有大佬写这样的代码,减少了代码行数,一起学习一下。
void dealQSort(int *arr, int left, int right)
{
if (left >= right)
return;
int i = left, j = right;
int flag = 1;
while (i < j)
{
if (arr[i] > arr[j])
{
int t = arr[i];
arr[i] = arr[j];
arr[j] = t;
flag = !flag;
}
flag ? i++ : j--;
}
dealQSort(arr, left, i - 1);
dealQSort(arr, i + 1, right);
}
三路快排
与界定值相同的元素不进行下次递归,对于重复元素多的情况效率高。时间复杂度最差也是二路快排的时间复杂度。
void treeQSort(int* arr, int left, int right) {
if (left >= right)
return;
int midL = left;
int midR = right + 1;
int i = left + 1;
int tmp = arr[left];
while (i < midR) {
if (arr[i] < tmp) {
int t = arr[i];
arr[i] = arr[midL + 1];
arr[midL + 1] = t;
++midL;
++i;
}
else if (arr[i] > tmp) {
int t = arr[i];
arr[i] = arr[midR - 1];
arr[midR - 1] = t;
--midR;
}
else
++i;
}
int t = arr[left];
arr[left] = arr[midL];
arr[midL] = t;
treeQSort(arr, left, midL - 1);
treeQSort(arr, midR, right);
}