Acwing 基础算法 1.1 快速排序、归并排序

前言 本文及其系列文章为作者学习算法时的笔记,略显潦草,如有错误,请及时指正,持续更新中······

快速排序(基于分治)

思路:(l : 左 , r : 右)

1、确定分界点x : q[ l ] , q[ (l + r)/2] , q[ r ] , 随机
2*、调整区间 ( i<=x )( j>=x )
3、递归处理左右两段


实现方法(暴力)
1、a[ ] , b[ ]
2、              / q[ i ]<=x , x->a[ ] 
     q[ l~r ]   
                   \ q[ i ]>=x , x->b[ ]
3、a[ ]->q[ ] , b[ ]->q[ ] 

实现方法(优美)
1、i=l , j=r
2、    若q[ i ]<x , ++i 直至 q[ i ]>x , 
执行   若q[ j ]>x , ++j 直至 q[ i ]<x , 若i>=j
执行   swap(q[ i ] , q[ j ]) , ++i , ++ j
重复以上操作 , 直至i , j相遇 ( i>=j ) 为止
3、递归处理左右两段{ ( l~j )( j+1~r )  or  ( l~i-1 )( i~r ) }重复以上操作 ( 注意考虑避开边界问题导致的死循环 : x=q[ l ]时 , 边界不能用第二种 , x=q[ r ]时 , 边界不能用第一种 )


代码实现

#include <iostream>

using namespace std;

const int N = 1e6 + 100;

int n;
int q[N];

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);
		do j--; while (q[j] > x);
		if (i < j)swap(q[i], q[j]);
	}
	quick_sort(q, l, j);
	quick_sort(q, j + 1, r);
}
int main() {
	scanf_s("%d", &n);
	for (int i = 0; i < n; i++)scanf_s("%d", &q[i]);
	
	quick_sort(q, 0, n-1);
	for (int i = 0; i < n; i++)printf("%d ", q[i]);
	return 0;
}

归并排序(基于分治)

思路:(l : 左 , r : 右)

1、确定分界点 : mid=( l+r )/2
2、递归处理左右两段
3*、归并 ( 合二为一 , 把两个有序数组和并成一个有序的数组 )


实现方法


代码实现

​
#include <iostream>

using namespace std;

const int N = 1e6 + 100;

int n;
int q[N],tmp[N];

void merge_sort(int q[], int l, int r) {
	if (l >= r)return;
	int mid = l + r >> 1;//(>>1)<=>(/2)
	merge_sort(q, l, mid);
	merge_sort(q, mid + 1, r);
	int k = 0, i = l, j = mid;
	while (i <= mid && j <= r) 
		if (q[i] <= q[j])tmp[k++] = q[i++];
		else tmp[k++] = q[j++];
	while (i <= mid)tmp[k++] = q[i++];
	while (j <= r)tmp[k++] = q[j++];
	
	for (int i = l, j = 0; i <= r; i++,j++)q[i] = tmp[j];
}

int main() {
	scanf_s("%d", &n);
	for (int i = 0; i < n; i++)scanf_s("%d", &q[i]);
	
	merge_sort(q, 0, n - 1);//归并排序
	for (int i = 0; i < n; i++)printf("%d ", q[i]);
	return 0;
}

​

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值