排序算法之分治

事情是这样的,上周因为得了甲流,导致了没去上算法课。

然后今天听说算法课留了作业(简直匪夷所思)

然后题目是:

给定一个数组,输出最小的两个数字。

我:这不秒杀?直接一个sort排序,再将前两个数给输出不就完了?

后来听说这个还需要用到分治的思想

啊,这得好好想想,想了好一会才想到用快速排序和归并排序???

(果然API函数越用越蠢,但是用的是真的爽啊!!!!)

既然这样咱就趁这次抄一下手写一次快速排序和归并排序

快速排序:

#include<iostream>
using namespace std;

const int N=1e5+10;

int arr[N];
void quick_sort(int l,int r)
{
  if(l>=r)return ;
  int i=l, j=r, x=arr[i];
		while(i<j) {
			while (i<j && arr[j]>x) {j--;} // 从右向左找第一个小于x的数
			if (i < j) {arr[i++] = arr[j];}// 将小于x的值放在左边
			while (i < j && arr[i] < x) {i++;}// 从左向右找第一个大于x的数
			if (i < j) {arr[j--] = arr[i];}// 将大于x的值放在右边
		}
		arr[i] = x;
		quick_sort(l, i - 1);
		quick_sort(i+1, r);
	}

int main()
{
  int n;
  cin>>n;
  for(int i=0;i<n;++i)
  cin>>arr[i];
  quick_sort(0,n-1);
 cout<<arr[0]<<"  "<<arr[1]<<endl; 
  return 0;
}

关于快速排序的算法,我们这里有几个细节

首先就是我们需要首先从右向左找小于x的值,再从左向右找第一个大于x的值

这个顺序不能换,至于为啥不能换,可以去模拟一下(由于这里只是记录一下作业,所以就不到此证明了)

其次就是这个递归的,不用递归第i个,因为第i个以及到了它该到的位置,所以就是:

quick_sort(l, i - 1);

和quick_sort(i+1, r);

归并排序:

#include<iostream>
using namespace std;

long long res=0;
const int N=100000+10;
int a[N],temp[N];

void merge_sort(int a[],int l,int r)
{
    if(l>=r)return ;
    int mid=l+r>>1;
    merge_sort(a,l,mid);
    merge_sort(a,mid+1,r);
    int i = l, j = mid + 1,k = 0;
    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(int i=l,j=0;i<=r;++i,++j) a[i]=temp[j];
}
int main()
{
    int n;
    cin>>n;
    for(int i=0;i<n;++i)cin>>a[i];
    merge_sort(a,0,n-1);
    cout<<a[0]<<" "<<a[1]<<endl;
    return 0;
}

归并排序也是一个典型的分治的排序算法

它这个思想就是创建一个数组和一个临时数组,

接下来将整个数组不断的分成一半一半,最后分到一个数组只有两个,再将两个进行排序

接着再将两个已经排好序的数组再合并一下,合并的临时数组里面。

最后将临时数组赋值到实际的数组里面

最后讲个小故事(我也忘记从哪里听来的)

据说以前人们研究排序算法,一直无法突破O(n^2),所以科学家们一直

以为排序算法的极限就是O(n^2)了,直到后来有个人发现了这个分而治之

的算法,也就发明了快速排序算法(好像是这个),后来就有不少人利用

类似的思想,最后就出现了好几种复杂度为O(nlogn)的算法。

那就记录到这里吧。

 end---

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值