前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >【算法系列01】:快速排序&&归并排序

【算法系列01】:快速排序&&归并排序

作者头像
小Bob来啦
发布2021-05-27 16:09:02
4680
发布2021-05-27 16:09:02
举报
文章被收录于专栏:用户8057608的专栏

你需要知道,人的事业就如同浪潮,如果你踩到浪头,功名随之而来;而一旦错失,则终其一生都将受困于浅滩与悲哀。

——《洛克菲勒写给儿子的38封信》

大家好哇,这里是小编记录算法模板的宝地啦,其中也会包含小编平时学习的一些心得。现在,让我们一起进入算法的世界吧~

1.快速排序

快速排序是在冒泡排序基础上的改进,其基本思想是基于分治

在写代码之前最好是找到自己要写代码的大致步骤:

  1. 找分界点:可以是数据的两端或中间,当然随机值也可。
  2. 调整区间:使得一个区间的数据小于一个值,另一个区间的值大于一个值。
  3. 递归处理:分别对两个区间进行递归处理。

To:在找分界点时,当数据加强后最好是不要选择两边端点的值,之前小编便遇到过内存过载的ERROR。

按照教材上说的,我们在进行快排时会使用两个数组,用于存放两个区间的值,存放之前还会对之前的数据进行扫描,对于时间复杂度和空间复杂度都是不小的开销。

y总提供了一种优美的解决方案,即用两个指针分别指向数据集的两端i、j,再取其分界点x。

大致思路是i和j分别向中间走,其中当i大于x时便停下来,j小于x时也是【假设从小到大排序】。然后当i和j两个指针都停下来,便交换两边的值。最后当两个指针相遇时,便确保了一个区间的值是小于x的,另一个区间的值大于x的。

快速排序例子:

输入格式

输入共两行,第一行包含整数 n。

第二行包含 n 个整数(所有整数均在 1∼10的9次方范围内),表示整个数列。

输出格式

输出共一行,包含 n个整数,表示排好序的数列。

数据范围

1≤n≤100000

输入样例:

5

3 1 2 4 5

输出样例:

1 2 3 4 5

源代码:

代码语言:javascript
复制
#include <iostream>

const int N=1e6+10;
int a[N];

void Sorttest(int l,int r){
     if(l>=r){
         return ;
     }
     //判断数据集
     int i=l-1,j=r+1;
     int x=a[(l+r)/2];
     //取中间值
     while(i<j){
         do i++;while(a[i]<x);
         do j--; while(a[j]>x);
         if(i<j){
             std::swap(a[i],a[j]);
             //交换数据
         }
     }
         Sorttest(l,j);Sorttest(j+1,r);
         //分别处理两个区间的数据
}
int main(){
using namespace std;
    int n,i;
    cin>>n;
    //输入排序数据集
    for(i=0;i<n;i++){
        scanf("%d",&a[i]);
    }
//Sorttest函数进行排序
    Sorttest(0,n-1);
//使用循环输出排序后的数据
    for(i=0;i<n;i++){
        printf("%d ",a[i]);
    }
return 0;
}

快速排序模板:

代码语言:javascript
复制
void Sorttest(int l,int r){
     if(l>=r){
         return ;
     }
     int i=l-1,j=r+1;
     int x=a[(l+r)/2];
     while(i<j){
         do i++;while(a[i]<x);
         do j--; while(a[j]>x);
         if(i<j){
             std::swap(a[i],a[j]);
         }
     }
         Sorttest(l,j);Sorttest(j+1,r);
}

To:可能会有人问为啥会有模板,在处理大部分排序时,模板都能起到很大的作用,平时可以多敲敲模板,关于临界值的处理则需要自己去记忆了。

2.归并排序

归并排序是一种稳定的排序,而快速排序则是一种不稳定的,归并排序也基于分治。

To:原序列中2个数相同,位置不发生变化我们便说这个排序是稳定的;反之则是不稳定的。

大致思路步骤为:

  1. 确定分界点,即mid=(l+r)/2。
  2. 递归排序左边和右边。
  3. 归并:合二为一,将排序后的数据合并,也是归并排序中最重要的一个环节。

在归并排序中,我们也用到两个指针,分别指向排好序数据的最左端,并开始比较,值小的就拿出来【以从小到大排序】放入另一个数组中,依次比较,如果遇到相等的数,我们倾向于将第一个序列的值先放入另一个数组中;如果当第一个指针指向序列的最后一个值时,我们便把另一个序列直接补到数组后面。

归并排序例子:

输入格式

输入共两行,第一行包含整数 n。

第二行包含 n 个整数(所有整数均在 1∼10的9次方范围内),表示整个数列。

输出格式

输出共一行,包含 n个整数,表示排好序的数列。

数据范围

1≤n≤100000

输入样例:

5

3 1 2 4 5

输出样例:

1 2 3 4 5

源代码:

代码语言:javascript
复制
#include<iostream>
using namespace std;

const int N = 1000010;
int a[N], temp[N], n;

void Sorttest(int a[], int l, int r) {
    if (l >= r) {
        return;
    }
//判断数据集
    int mid = l + r >> 1;
//取中间值
    Sorttest(a, l, mid);
    Sorttest(a, mid + 1, r);
//递归左右两边
    int k = 0, i = l, j = mid + 1;
    while (i <= mid && j <= r)
        if (a[i] <= a[j]) {
            temp[k++] = a[i++];
        } else {
            temp[k++] = a[j++];
        }
//排序:比较大小,将较小的数据放入temp数组中
    while (i <= mid) temp[k++] = a[i++];
    while (j <= r) temp[k++] = a[j++];
//判断某一个序列是否未放入temp数组中,并将其放入
    for (i = l, j = 0; i <= r; i++, j++) {
        a[i] = temp[j];
    }
}

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

    Sorttest(a, 0, n - 1);

    for (int i = 0; i < n; i++) {
        printf("%d ", a[i]);
    }
    return 0;
}

归并排序模板:

代码语言:javascript
复制
void Sorttest(int a[], int l, int r) {
    if (l >= r) {
        return;
    }

    int mid = l + r >> 1;

    Sorttest(a, l, mid);
    Sorttest(a, mid + 1, r);

    int k = 0, i = l, j = mid + 1;
    while (i <= mid && j <= r)
        if (a[i] <= a[j]) {
            temp[k++] = a[i++];
        } else {
            temp[k++] = a[j++];
        }
    while (i <= mid) temp[k++] = a[i++];
    while (j <= r) temp[k++] = a[j++];
    for (i = l, j = 0; i <= r; i++, j++) {
        a[i] = temp[j];
    }
}

平时也可多敲敲模板哦!

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2021-05-13,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 程序员Bob 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档