算法基础课

 

 

 快排代码:

#include <iostream>
using namespace std;
const int N = 1e6+1;
int a[N];
void qsort(int l,int r)
{
    if(l >= r) return ;
    int i = l -1, j = r+1,x = a[l+r>>1];
    while(i < j)
    {
        do i++;while(a[i] < x);
        do j--;while(a[j] > x);
        if(i < j) swap(a[i],a[j]);
    }
    qsort(l,j);qsort(j+1,r);
}
int main()
{
    std::ios::sync_with_stdio(false);
    int n;
    cin>>n;
    for(int i = 0;i<n;i++)
        cin>>a[i];
    qsort(0,n-1);
    for(int i = 0;i<n;i++)
        cout<<a[i]<<" ";
    return 0;
}

快排如果要把j换成i的话,qsort(l, i-1);qsort(i,r);那么设定的比较的数字就不能是q[l]。int x = q[r];

当用j作为边界的时候:qsort(l,j);qsort(j+1,r);那么设定的比较数字就不能是q[r];int x = q[l];

 

 

 

 

归并排序代码:

#include <iostream>

using namespace std;
const int N = 1e6+10;
int a[N],tmp[N];
void qsort(int l,int r)
{
    if(l >= r) return;
    int mid = l + r >> 1;
    qsort(l,mid);qsort(mid+1,r);
    int i = l,j = mid+1,k = 0;
    while(i <= mid && 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(i = l,j=0;i<=r;i++,j++)
        a[i] = tmp[j];
}
int main()
{
    std::ios::sync_with_stdio(false);
    int n;
    cin>>n;
    for(int i = 0;i<n;i++)
        cin>>a[i];
    qsort(0,n-1);
    for(int i = 0;i<n;i++)
        cout<<a[i]<<" ";

    return 0;
}

 

 比较sort函数、快排、归并三种排序方式耗时,——>>发现三者其实所耗的时间相差无几。

二分:

  整数二分:

int bsearch_1(int l, int r)
{
    while (l < r) {
        int mid = l + r >> 1;
        if(check(mid)) r = mid;
        else l  = mid + 1;
    }
    return l;
}

int bsearch_2(int l, int r)
{
    while (l < r) {
        int mid = (l + r + 1) >> 1;
        if(check(mid)) l = mid;
        else r = mid - 1;
    }
    return l;
}

  整数查询开始位置和结束的位置:

#include <iostream>

using namespace std;

const int N = 100010;

int n,m;
int q[N];

int main()
{
    scanf("%d%d",&n,&m);
    for(int i  = 0;i<n;i++) scanf("%d",&q[i]);
    
    while(m--)
    {
        int x;
        scanf("%d",&x);
        int l = 0, r = n - 1;
        while(l < r)
        {
            int mid = (l + r) >> 1;
            if(q[mid] >= x) r = mid;//找到左边第一个出现x的位置,若中点都大于x,那么起始点肯定在左侧,就令r = mid;
            else l = mid + 1;
        }
        
        if(q[l] != x) cout<<"-1 -1"<<endl;//如果x不存在,那么找到的是第一个>=x的数字
        else
        {
            cout<<l<<' ';//先找到x开始的位置输出
            
            int l = 0, r = n - 1;
            while(l < r)
            {
                int mid = (l + r + 1) >> 1;
                if(q[mid] <= x) l = mid;//找到最后一个出现x的位置,若中点的位置都<=x,那么x结束的位置肯定在mid的右半部分,所以令l = mid;
                else r = mid - 1;
            }
            cout<<l<<endl;
        }
    }
    
    return 0;
}

 

 浮点数二分:

#include <iostream>

using namespace std;

int main()
{
    double x;
    cin>>x;
    
    double l = -1e5, r = 1e5;
    while(r - l > 1e-8)
    {
        double mid = (l + r) / 2;
        if(mid * mid * mid >= x) r = mid;
        else l = mid;
    }
    
    printf("%.6lf\n",l);
    
    return 0;
}

 

 不用精度,而是直接循环一百次:

#include <iostream>

using namespace std;

int main()
{
    double x;
    cin>>x;
    
    double l = -1e5, r = 1e5;
    for(int i = 0;i<100;i++)
    {
        double mid = (l + r) / 2;
        if(mid * mid * mid >= x) r = mid;
        else l = mid;
    }
    
    printf("%.6lf\n",l);
    
    return 0;
}

 

 

posted @ 2020-02-28 15:26  龙雪可可  阅读(140)  评论(0编辑  收藏  举报
****************************************** 页脚Html代码 ******************************************