0
点赞
收藏
分享

微信扫一扫

设计模式12--组合模式

一.快速排序(升序为例)

思想:确定分界点x,将小于分界点的值放在分界点的左边,将大于分界定的值放在分界点的右边,再递归处理两边的左右区间。

步骤:

1.确定分界点:分界定的确定是随机的,一般取中间点(mid)和左右(L,R)边界点

2.调整区间:将小于分界点的值放在分界点的左边,将大于分界定的值放在分界点的右边(降序相反)

3.递归:递归处理左右两边,重复上述操作

调整区间的实现方式:

1.可以开辟两个空间来存放分界点的值,然后再拷贝回去,但这样会额外消耗空间

2.双指针法:L为左边界,R为右边界,用i 从L出发,用j 从R出发,i 向前遍历,直到遇到大于分界点x 的值并停下来,j 向后遍历,直到遇到小于x 的值并停下来,接着i 与j 指向的值交换,再继续重复上述操作直到i 与 j 相遇。

快排模板--O(N*logN)

void quick_sort(int q[], int l, int r)
{
	//只剩一个数,就不需要再操作了
	if (l >= r) return;
	//这里-1和+1是因为后面的do while操作
	int i = l - 1, j = r + 1;
	int x = q[(l + r) >> 1];
	while (i < j)
	{
		do i++;
		while (q[i] < x);
		do j--;
		while (q[j] > x);
		//这里需要判断,因为有可能会出现i == j
		if (i < j)
			swap(q[i], q[j]);
	}
	//递归左右两边
	quick_sort(q, l, j);
	quick_sort(q, j + 1, r);
}

二.归并排序(升序为例)

思想:将两个有序数组合并成一个有序数组,那么归并排序整体就是先递归排序,再将有序数组合并成一个数组

 步骤:
1.确定分界定:mid = (l + r) >> 1;

2.递归排序左边和右边

3.将两个有序的数组合并成一个数组--双指针遍历两个数组比较大小

归并模板--O(N*logN)

const int N = 100010;
int temp[N];
void merge_sort(int q[], int l, int r)
{
	if (l >= r) return;
	int mid = (l + r) >> 1;
	merge_sort(q, l, mid);
	merge_sort(q, mid + 1, r);
	//合并
	int index = 0, i = l, j = mid + 1;
	while (i <= mid && j <= r)
	{
		if (q[i] < q[j]) temp[index++] = q[i++];
		else temp[index++] = q[j++];
	}
	while (i <= mid) temp[index++] = q[i++];
	while (j <= r) temp[index++] = q[j++];
	//拷贝回去
	for (i = l, index = 0; i <= r; i++,index++)
	{
		q[i] = temp[index];
	}
}
举报

相关推荐

0 条评论