分治法 之 归并排序,快速排序 初学通俗版

分治法

大问题拆分成小问题,有共同的解决办法,小问题解决完合并后大问题就迎刃而解

归并排序

归并的名字就是先分,又合并,合并完排序

很稳定

把数组分成两部分,两部分分成四部分,四部分分成八部分

每一部分就剩两个了,进行排序调换

两个部分在合并,排序调换

两个部分(四个部分)在合并,排序调换

#include<stdio.h>
const int N = 1e6 + 1;
int q[N],temp[N];//原数组,预留数组
void merge_sort(int q[], int l, int r)
{
	if (l >= r) //回溯
		return;
	int mid = (l + r) / 2,i=l,j=mid+1,k=0; //二分  
	merge_sort(q, l, mid);//对中点左区间排序     //第一层回溯完l=mid  //回溯完是排好序的左区间
	merge_sort(q, mid+1,r);//对中点右区间排序   //第一层回溯完mid+1=r //回溯完是排好序的左区间
	while (i <= mid && j <= r)//第一层回溯  i=mid-1,j=r
	{
		if (q[i] >= q[j])        //存小的
			temp[k++] = q[j++];
		else
			temp[k++] = q[i++];
	}
	while (i <= mid) temp[k++] = q[i++];//没存完的继续存
	while (j <= r) temp[k++] = q[j++];//没存完的继续存
	for (i = l, j = 0; i <= r; i++, j++) q[i] = temp[j]; //存完的还回去
}
int main()
{
	int n;
	scanf("%d", &n);
	for (int i = 0; i < n; i++) scanf("%d", &q[i]);
	merge_sort(q, 0, n - 1);
	for (int i = 0; i < n; i++) printf("%d ", q[i]);

}

快速排序

不需要合并了,是拆分,排好序后分。速度很快就叫快速排序

但是不稳定又好用

不是以中点分了,随便找个点分,这个点叫基点,分好后左边是小于这个点的,右边是大于这个点的,如果不是,就左右的两个不符合的点调换,类似于双指针

先找好基点,大小放好后,在进行分

分的时候还是左右区间,每个区间在按照基点左小右大换,换完分,到最后就是全部都能左小右大了

#include<stdio.h>
const int N = 1e6 + 10;
int n;
int q[N];
void swap(int *a, int *b)  //交换
{
	int t;
	t = *a;
	*a = *b;
	*b = t;

}
void quick_sort(int q[], int l, int r)
{
	if (l >= r)//回溯
		return;
	int x = q[l], i = l - 1, j = r + 1;//以左边界为基点
	while (i < j)//重合退出循环
	{
		do  i++;  while (q[i] < x);//i,比基点小就向右移动
		do  j--;  while (q[j] > x);//j,比基点大就向左移动
		if (i < j)                 //i移动到大于基点的位置,不符合要求,j同理,所以互换
			swap(&q[i], &q[j]);    //交换二者
	}//在基点的左右两端达到左小右大
	quick_sort(q, l, j);//j,i相当于基点的位置,对基点的左区间在继续排序
	quick_sort(q, j + 1, r);//对基点的右区间在继续排序

}
int main()
{
	scanf("%d", &n);
	for (int i = 0; i < n; i++) scanf("%d", &q[i]);
	quick_sort(q, 0, n-1);
	for (int i = 0; i < n; i++) printf("%d ", q[i]);
	printf("\n");
	return 0;
}

小萌新一枚~多多指正呀~

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值