Algorithm Course Review(1.2)

  几种经典的查找和排序算法。

  查找算法有线性查找,二分查找。线性查找就是遍历所有元素,直到找到目标元素,时间复杂度为O(n),相对于输入规模是线性的。二分查找,在数组已经排序的情况下,可以进行二分查找,每次缩小一半的查找范围,时间复杂度为O(logn)。需要注意的是,算法里面的log表示log2.

  这两个算法的代码如下:

#include <vector>
#include <iostream>
using namespace std;

/*
 * 线性查找,即遍历所有元素查找
 */ 
template<class Type>
int LinearSearch(vector<Type>& A, Type x)
{
    int j = -1;
    for(unsigned int i=0;i<A.size();i++)
    {
        if(x==A[i])
        {    
            j = i;
            break;
        }
    }
    return j;
}

/*
 * 二分查找,即对半查找,要求数组已排序
 */ 
template<class Type>
int BinarySearch(vector<Type>& A, Type x)
{
    int low = 0;
    int high = A.size()-1;
    int j = -1;
    while(low<=high && j==-1)
    {
        int mid = (low+high)/2;
        if(x==A[mid])
            j = mid;
        else if(x<A[mid])
            high = mid-1;
        else
            low = mid+1;
    }
    return j;
}

  再看排序算法,主要有选择排序,插入排序,归并排序和快速排序。

  选择排序,就是处理第i个元素时,从剩余的元素里面选出最小的,与i位置元素交换,那么就是把第i小的元素放在第i个位置,即选择过程。比较次数n(n-1)/2.

  插入排序,从第二个元素开始,处理第i个元素时,从前面的元素里找出比第i个元素小的位置j,那么x就应该排在j的后面,也即插入过程。比较次数也是n(n-1)/2.

  快速排序,通过一次快速排序,将数组的元素分为独立的两部分,其中一部分的所有元素比另一部分小。然后对这两部分再进行快速排序,递归实现。

  归并排序,通过归并步骤,将两个有序数组合并为一个有序数组。归并排序,就是将数组不断划分为小的数组,数组长度为1时,即为一个有序数组,然后逐级归并,实现排序。

  代码如下:

#include <vector>
#include <iostream>
using namespace std;

/*
 * 每次从剩余的元素里面找出最小的,
 * 放在第i个位置,那么就是第i个位置放的元素是第i小的,
 * 即选择过程
 */ 
template<class Type>
void SelectSort(vector<Type>& A)
{
    int i=0,j=0,k=0;
    int n=A.size();
    for(i=0;i<n-1;i++)
    {
        k = i;
        for(j=i+1;j<n;j++)
        {
            if(A[j]<A[k])
                k = j;
        }
        if(k!=i)
        {
            Type t = A[k];
            A[k] = A[i];
            A[i] = t;
        }
    }
}

/* 每次在前面找到x的合适位置,
 * A[j]<x时,把x放在A[j+1]上
 * 即插入过程
 */
template<class Type>
void InsertSort(vector<Type>& A)
{
    int i=0,j=0;
    int n = A.size();
    for(i=1;i<n;i++)
    {
        Type x=A[i];
        j=i-1;
        while(j>=0 && A[j]>x)
        {
            A[j+1]=A[j];
            j=j-1;
        }
        A[j+1]=x;
    }
}
/*
 * 通过一趟快速排序将数据分割成独立的两部分,
 * 其中一部分比另外一部分的所有数据都要小,
 * 然后再对这两部分数据分别进行快速排序
 * ref: http://blog.csdn.net/shiwenbin333/article/details/4528516
 */ 
template<class Type>
void quicksort(vector<Type>& A,int left,int right)
{
    Type temp = A[left];
    int i=left+1;
    int j=right;
    int cur=left;
    bool direction = false;
    while(i<=j)
    {
        if(direction)
        {
            if(A[i]>temp)
            {
                A[cur] = A[i];
                cur = i;
                direction = false;
            }
            i++;
        }
        else
        {
            if(A[j]<temp)
            {
                A[cur] = A[j];
                cur = j;
                direction = true;
            }
            j--;
        }
    }
    A[cur] = temp;
    if(cur-left>1)
        quicksort(A,left,cur-1);
    if(right-cur>1)
        quicksort(A,cur+1,right);
}

template<class Type>
void QuickSort(vector<Type>& A)
{
    quicksort(A,0,A.size()-1);
}

/*
 * 归并步骤,将两个有序数组合并为一个有序数组
 */ 
template<class Type>
void mergearray(vector<Type>& A,int p,int q,int r)
{
    vector<Type> B(r-p+1);
    int s=p,t=q+1,k=0;
    while(s<=q && t<=r)
    {
        if(A[s]<=A[t])
        {
            B[k] = A[s];
            s = s + 1;
        }
        else
        {
            B[k] = A[t];
            t = t + 1;
        }
        k = k + 1;
    }
    while(s<=q)
        B[k++]=A[s++];
    while(t<=r)
        B[k++]=A[t++];
    for(s=0;s<k;s++)
        A[p+s]=B[s];
}

/*
 *  归并排序,将数组不断划分,然后逐级归并,实现排序
 *  ref: http://blog.csdn.net/morewindows/article/details/6678165
 */ 
template<class Type>
void mergesort(vector<Type>& A,int p,int r)
{
    if(p<r)
    {
        int mid = (p+r)/2;
        mergesort(A,p,mid);
        mergesort(A,mid+1,r);
        mergearray(A,p,mid,r);
    }
}

template<class Type>
void MergeSort(vector<Type>& A)
{
    mergesort(A,0,A.size()-1);
}


template<class Type>
void print(vector<Type>& A)
{
    for(unsigned int i=0;i<A.size();i++)
        cout << "\t" << A[i];
    cout << endl;
}

int main()
{
    int b[] = {9,3,2,6,4,5,8,7};
    vector<int> A(b,b+8);
    print(A);
//    SelectSort(A);
//    InsertSort(A);
//    QuickSort(A);
    MergeSort(A);    
    print(A);
    return 0;
}

  上面的程序还可以优化。

  先到这里,有空再继续。

posted @ 2012-05-13 21:28  Frandy.CH  阅读(218)  评论(0编辑  收藏  举报