基础算法----排序

一、快排

(一) 思想:           

1.核心思想:分治---分而治之

2.思路     1️⃣确定分界点(找个基数x):q[l],q[r]等。

               2️⃣调整区间:分成小于x和大于等于x两部分。(用双指针(对撞))

               3️⃣递归处理左右两段。

思路总结举例

  1. 先确定分界点    在此选择q【l】
  2. 用双指针调整区间,i指向l,j指向r。j先向左移动(基数在最左的前提下)直到j指向数据小于x停止,再i向右动直到i指向数据大于x停止。然后i与j所指数据互换。
  3. 重复2过程。直到i与j碰撞,则其所指数据与q【l】所指数据互换(j先动的原因(可以自己推导一下)),区间调整完成。
  4. 递归2.3过程。 

注:当基准数选择最左边的数字时,那么就应该先从右边开始搜索;当基准数选择最右边的数字时,那么就应该先从左边开始搜索。不论是从小到大排序还是从大到小排序! 

(二)模板:从小到大排序(大到小同理) 

效率较低但通俗易懂(大概是过不了的🤭)

void quicklysort(int l,int r,vector<int>&q)
{
	if (l >= r)
		return;
	int i, j, base, temp;
	i = l, j = r;
	base = q[l];//确定分界点
	while (i < j)//双指针
	{
		while (q[j] >= base && i < j)
			j--;
		while (q[i] <= base && i < j)
			i++;
		if (i < j)
			swap(q[i], q[j]);
	}
	//基准点归位
	q[l] = q[i];
	q[i] = base;
	//递归左右两段
	quicklysort(l, i - 1, q);
	quicklysort(i + 1, r, q);
}

能过得了的 

#include <bits/stdc++.h>
using namespace std;
const int N = 1e5 + 10;
int a[N], n;

void quick_sort(int l, int r)
{
    if (l >= r) return ;
    swap(a[l], a[l + rand() % (r - l + 1)]);
    int i = l - 1, j = r + 1, x = a[l];
    while (i < j)
    {
        while (a[ ++ i] < x)    ;
        while (a[ -- j] > x)    ;
        if (i < j)  swap(a[i], a[j]);
    }
    quick_sort(l, j);
    quick_sort(j + 1, r);
}

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

 二、归并排序

(一)思想----分治

分治思想:先拆成最小单元,再按顺序依次归并。

思路:

  1. 分界点    mid = (l+r)/2
  2. 递归排序:分成左右两部分

     3.归并(合二为一)用快慢指针

(二)、模板

​
​
#include <bits/stdc++.h>
using namespace std;
const int N = 1e5 + 10;
int q[N], tmp[N], n;

void merge_sort(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 k = 0, i = l, j = mid + 1;
    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 (i = l, j = 0; i <= r; i ++, j ++ ) q[i] = tmp[j];
}


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

​

​

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值