2.1基础算法(排序)

1.快速排序:基本思想是分治,时间复杂度nlog(n)

1)确定分界点

2)调整区间

3)递归处理左右两段

#include <iostream>
#include <cstdio>
using namespace std;
const int N = 100010;
int a[N];
void quick_sort(int a[] , int l , int r){
    if(l>=r) return ;
    int x = a[l+r>>1], i = l - 1 , j = r + 1;
    while(i<j){
        do i++; while(a[i]<x);//可以写while(a[++1]<x),适于没有do-while的语言
        do j--; while(a[j]>x);
        if(i<j) swap(a[i],a[j]);
    }
    quick_sort(a,l,j);
    quick_sort(a,j+1,r);
}
int main()
{
    int n;
    scanf("%d", &n);
    for (int i = 0; i < n; i ++ ) scanf("%d", &a[i]);
    quick_sort(a,0,n-1);
    for (int i = 0; i < n; i ++ ) printf("%d ", a[i]);
    return 0;
}

2.归并排序 基本思想:分治 , 时间复杂度nlog(n)

1)确定分界点mid = (l + r)/2 ,和快速排序的区别是快排的分界点是值,归并的分界点是数组下标

2)递归排序左边和右边

3)合并

#include <iostream>
using namespace std;
const int N = 100010;
int a[N],tmp[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 k = 0 , i = l , j = mid+1;
    while(i<=mid and j<=r){
        if(a[i]<=a[j]) tmp[k++]=a[i++];
        else  tmp[k++]=a[j++];
    }
    while(i<=mid) tmp[k++]=a[i++];
    while(j<=r) tmp[k++]=a[j++];
    for(int i = l , j = 0 ; i <= r ; i++ , j++) a[i]=tmp[j];
}
int main()
{
    int n;
    scanf("%d", &n);
    for (int i = 0; i < n; i ++ ) scanf("%d", &a[i]);
    merge_sort(a,0,n-1);
    for (int i = 0; i < n; i ++ ) printf("%d ",a[i]);
    return 0;
}

3)二分

找到的是从左往右第一个满足>=x的数

 

 

整数二分:

#include <iostream>
using namespace std;
const int N = 100010;
int a[N];
int main()
{
    int n,m;
    scanf("%d%d", &n, &m);
    for (int i = 0; i < n; i ++ ) scanf("%d", &a[i]);
    while (m -- ){
        int x;
        scanf("%d", &x);
        int l = 0 , r = n-1;
        while(l<r){
            int mid = l+r>>1;
            if(a[mid]>=x) r = mid;
            else l = mid+1;
        }
        if(a[l]!=x) printf("-1 -1\n");
        else{
            printf("%d ",l);
            int l = 0 , r = n-1;
            while(l<r){
                int mid = l+r+1>>1;
                if(a[mid]<=x) l = mid;
                else r = mid-1;
            }
            printf("%d\n",l);
        }
    }
    return 0;
}

 浮点数二分:

输入浮点数x,找到x的平方根,结果保留6位小数

#include <iostream>
using namespace std;
int main()
{
    double x;
    scanf("%lf", &x);
    double l = 0 , r = x;
    while(r-l>1e-8){
        double mid = (l+r)/2;
        if(mid*mid>=x) r = mid;
        else l = mid;
    }
    printf("%.6lf\n",l);
    return 0;
}

保留几位小数,循环的时候就多写两位,比如6位小数写1e-8 ;

posted @ 2021-11-13 12:00  乐池  阅读(30)  评论(0)    收藏  举报