【AcWing】Day1 排序

一、快速排序

分治法:

区间为l到r,x

1.确定分界点q[l],q[(l+r)/2],q[r]
2.调整区间,通过x值划分为两部分,使得第一个区间所有数小于等于x,第二个区间所有数大于等于x,数等于x的话在第一或第二区间都可以
3.递归处理左右两段,分别排序,整个区间就排好序了。
第二个的解决方式1(浪费空间)

1.开数组a[ ],b[ ]
2.扫描整个区间q[l~r],若q[i]<=x,x->a[ ];若q[i]》=x,x->b[]
3.把a[ ]数放入q[ ],把b[ ]数放入q[ ]

第二个的解决方式2(优美)

指针法,将指针i指向q[l],指针j指向q[r],
1.第一个指针在左边是I。然后第二指针在右边是j,两个指针同时往中间走啊,就是分别往中间走。I先往中间走,这个数如果要是小于这x的话,最终的话就应该是在左半边.I就往后移动一位,
2.直到说某一次指向的这个数大于等于x了,这个数的话就应该放到右边去,那么我们就I就停下来。
3.然后再去移动J的话也是一样的道理,对称来看j的话就是说如果说我j指向的这个数要大于x的话 就应该放到右边
那么我们的J就一直往中间走啊,直到这个数它小于等于x了,
4.就两个数,其实都错位了,因此我们此时把这两个数交换一下就好了。把I指向的数和j指向的数交换一下swap一下。

# include <iostream>
using namespace std;
const int N=1e6+10;
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,l,i-1)如果此处为i,那么x=q[]不能取l,否则会出现死循环,j同理
    quick_sort(q,j+1,r);//quick_sort(q,i,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]);
    return 0;
}

二、归并排序

分治法:

以数组(区间为l到r) 的中心点来分

1.确定分界点:mid=(l+r)/2
2.递归排序,左右两边,得到两个有序数组
3.两个有序数组合二为一
第三步为重要部分
双指针算法

数组a[ ],数组b[ ]
指针i指向数组a[ ]的第一个元素,指针j指向数组b[ ]的第一个元素,a[i]与b[j]进行比较,也就是两个有序数组的最小值进行比较,
比如得到a[i]是最小的,那么a[i]就是整个数组最小的值,则i++,则a[i]>b[j],则j++;当i和j任意一个走到尽头的时候,剩下的那一部分数组就是最大的一部分值,直接放在后边就好

# include <iostream>
using namespace std;
const int N=1e6+10;
int n;
int q[N],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 k=0,i=l,j=mid+1;
    while (i<=mid && j<=r)
        if (q[i]<=q[j]) temp[k++]=q[i++];
        else temp[k++]=q[j++];
    while(i<=mid)   temp[k++]=q[i++];
    while(j<=r) temp[k++]=q[j++];
    //将temp放回q
    for(i=l,j=0;i<=r;i++,j++)   q[i]=temp[j];
}

int main()
{
    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]);
    return 0;
}

排序稳定

一个排序算法是稳定的,并不是说它时间效率是稳定。稳定是指如果说我这个原序列当中两个数的值是相同的,原序列里边两个数的值是相同的。他们在排完序之后,他们的位置如果要是不发生变化的话那么这个排序就是稳定的。他们的位置,如果要是可能会发生变化的话那么这个排序就是不稳定的。
快速排序是不稳定的,归并排序是稳定的,要将快速排序改成一个稳定的,只需要变成一个二元组。

时间复杂度

都是nlogn

猜你喜欢

转载自blog.csdn.net/m0_70098011/article/details/137245083