一、快速排序
分治法:
区间为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