快速排序和归并排序的分治思想(快排优化,三路快排)

归并排序
归并排序注重考察我们的递归分治思想,虽然做了很多递归分治思想的题,突然让我写归并,还是不知该怎么写。

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);
}

你可能感兴趣的:(快速排序和归并排序的分治思想(快排优化,三路快排))