算法与程序设计第二章分治法

思维导图

 补充信息

分治法一般的算法设计模式(分、治、合)

divide-and-conquer(p){
    if(|P|<=n0)
        adnoc(p);
    divide P into smaller subinstances P1,P2,……Pk;
    for(i=1;i<=k;i++)
        yi=divide-and-conquer(Pi);
    return merge(y1,y2,……,yk);
}

二分搜索算法

template <class Type>
int BinarySearch(Type a[],const Type& x,int n)
{
    int left=0;
    int right=n-1;
    while(left<=right){
        int middle=(left+right)/2;
        if(x==a[middle])
            return middle;
        else if(x>a[middle])
            left=middle+1;
        else
            right=middle-1;
    }
}

 合并排序(递归)

template <class Type>
void MergeSort(Type a[],int left,int right)
{
    if(left<right){
        int i=(left+right)/2;//取中点
        MergeSort(a,left,i);
        MergeSort(a,i+1,right);
        Merge(a,b,left,i,right);//合并到数组b
        Copy(a,b,left,right);//复制回数组a
    }
}

合并排序(非递归)

template<class Type>
void MergeSort(Type a[],int n)
{
    Type *b=new Type [n];
    int s=1;
    while(s<n){
        MergePass(a,b,s,n);//合并到数组b
        s+=s;
        MergePass(b,a,s,n);//合并到数组a
        s+=s;
    }
}

快速排序

template<class Type>
void QuickSort(Type a[],int p,int r)
{
    if(p<r)
    {
        int q=Partition(a,p,r);
        QuickSort(a,p,q-1);//对左半段排序
        QuickSort(a,q+1,r);//对右半段排序
    }
}

int Partition(Type a[],int p,int r)
{
    int i=p,j=r+1;
    Type x=a[p];
    while(1){
        while(a[++i]<x&&i<r);
        while(b[--j]>x);
        if(i>=j)
            break;
        Swap(a[i],a[j]);
    }
    a[p]=a[j];
    a[j]=x;
    return j
}

快速排序(随机化)

template <class Type>
void RandomizedQuickSort(Type a[],int p,int r)
{
    if(p<r){
        int q=RandomizedPartiton(a,p,r);
        RandomizedQuickSort(a,p,q-1);//左半段排序
        RandomizedQuickSort(a,q+1,r);//右半段排序
    }
}
int RandomizedPartition(Type a[],int p,int r)
{
    int i=Random(p,r);
    Swap(a[i],a[p]);
    return Partition(a,p,r)
}

分治法求二维点集最接近点对

bool Cpair2(S,d)
{
    n=|S|;
    if(n<2){d=∞;return false;}
    1.m=S中个点x间坐标的中位数;
    构造S1和S2;
    //S1={p∈S|x(p)<=m},S2={p∈S|x(p)>m}
    2.Cpair2(S1,d1);
    Cparir2(S1,d2);
    3.dm=min(d1,d2);
    4.设P1时S1中距垂直分割线l的距离在dm之内的所有点组成的集合;
    P2是S2中据分割线l的距离在dm之内的所有的点组成的集合;
    将P1和P2中点依y坐标值排序;
    并设X和Y是相应的已排好序的点列;
    5.通过扫描X以及对于X中每个点检查Y中与其距离在dm之内的所有点(最多6个)可以完成合并;
    当X中的扫描指针逐次向上移动时,Y中的扫描指针可在宽为2dm的一个区间内移动;
    设d1是按这种扫描方式找到的点对间的最小距离;
    6.d=min(dm,d1);
    return ture;
}

线性时间选择(第k小)

template <class Type>
Type RandomizedSelect(Type a[],int p,int r,int k)
{
    if(p==r)
        return a[p];
    int i=RandomizedPartition(a,p,r);
    j=i-p+1;
    if(k<=j)
        return RandomizedSelect(a,p,i,k);
    else return RandomizedSelect(a,i+1,r,k-j);
}

循坏赛日程表

void Table(int k)
{
    if(k==2){
        a[0][0]=2;
        a[1][0]=1;
    }
    else{
        Table(k/2);
        copyToLB(k/2);
        copyToRT(k/2);
        copyToRB(k/2);
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值