算法学习(一):递归与分治策略(2)

几个经典题目

1.二分搜索:给定已排好序的n个元素a[0:n-1],现要在这n个元素中找出一指定元素x。

比较简单,直接贴代码

int binary_search(int a[],int x)//二分搜索,找到x返回角标,不存在则返回-1;
{
   int low=0,high=n-1;
   while(low<=high)
   {
       int mid=(low+high)/2;
       if(a[mid]==x)
        return mid;
       else if(a[mid]>x)
        high=mid-1;//左搜索
       else
        low=mid+1;//右搜索
   }
   return -1;
}

2归并排序

对于两个有序数组,可通过一重循环,将其排序。将数组逐次分割,最后分割n个数组,可以认为此数组有序。然后在往回归并,最终得到有序数列。

完整代码如下:

#include <iostream>

using namespace std;
void merge_div(int low,int high);//分割,归并
void merge_sort(int low,int high,int mid);//排序
int a[10]={3,16,2,19,75,38,76,1};
void input();
int main()
{
    merge_div(0,7);
    input();
    return 0;
}
void merge_div(int low,int high)
{
    if(low>=high)
        return ;
    int mid=(low+high)/2;
    merge_div(low,mid);
    merge_div(mid+1,high);
    merge_sort(low,high,mid);
}
void merge_sort(int low,int high,int mid)
{
    int i=low,m=mid;
    int j=mid+1,n=high;
    int k=0;
    int t[20];
    while(i<=m&&j<=n)//对两个有序数组进行排序,并存到临时数组中
    {
        if(a[i]<a[j])
            t[k++]=a[i++];
        else
            t[k++]=a[j++];
    }
    while(i<=m)
        t[k++]=a[i++];
    while(j<=n)
        t[k++]=a[j++];
    k=0;
    for(int i=low;i<=high;i++)//将临时数组中的有序数列复制到原数组中
        a[i]=t[k++];
}
void input()
{
    for(int i=0;i<7;i++)
        cout<<a[i]<<" ";
    cout<<a[7]<<endl;
    return ;
}

3.快速排序

所谓快速排序,就是用最快的速度,将数组排好序。对于数组a[p:r]其基本思想及步骤是:

①:分解:以a[p]为基准元素将a[p:r]划分成3段a[p:q-1],a[q]和a[q+1:r],使得a[p:q-1]中任何元素小于等于a[q],a[q+1,r]中任何元素大于等于a[q]。下标q在划分过程中确定。

②:排序:递归调用快速排序算法,分别对分好的区间排序

③:合并:在找点的过程中,以排好序,所以合并后已然排好序。

完整代码如下:

#include <iostream>
/*
    快速排序算法
*/
using namespace std;
int n;
int a[100];
void readdata();
void quicksort(int low,int high);
int position(int low,int high);
void input();
int main()
{
    readdata();//读入数据
    quicksort(0,n-1);//调用快速排序算法
    input();//输出已排好序的数列
    return 0;
}
void readdata()
{
    cin>>n;
    for(int i=0; i<n; i++)
        cin>>a[i];
}
void quicksort(int low,int high)
{
    int pos;
    if(low<=high)
    {
        pos=position(low,high);//此点将数组分为两组,左边都比此点数据小,右边都比此点数据大
        quicksort(low,pos-1);//对左边调用快排
        quicksort(pos+1,high);//对右边调用快排
    }
    return ;
}
int position(int low,int high)
{
    int num=a[low];
    int i=low,j=high;
    while(i<j)
    {
        while(i<j&&a[j]>num)//从右向左找比num小的点。注意i<j是必要条件,否则会出bug
            j--;
        if(i<j)//将此点赋值给当前目标点位置
        {
            a[i]=a[j];
            i++;
        }
        while(i<j&&a[i]<num)//从左向右找比num大的点。注意i<j是必要条件,否则会出bug
            i++;
        if(i<j)//将此点赋值给当前目标点位置
        {
            a[j]=a[i];
            j--;
        }

    }
    a[i]=num;//将num赋值给找到的位置
    return i;//返回位置点
}
void input()
{
    for(int i=0;i<n-1;i++)
        cout<<a[i]<<" ";
    cout<<a[n-1]<<endl;
}


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章