排序算法(一)


这个学期课程很少,空闲时间很多,故重新复习了一下《算法导论》中的常用算法和数据结构,并且将实现代码保存到博客,以便大三暑假找实习时方便复习。。。。

(1)插入排序

直接插入排序的思想非常简单,将序列中第一个元素作为一个有序序列,然后将剩下的n-1个元素按关键字大小依此插入该有序序列,每插入一个元素后依然保持该序列有序,经过n-1趟排序后即成为有序序列。该算法的时间复杂度是O(n^2)。
template<typename T>
void insertionSort(T *A, int length)
{
    for(int i = 1; i < length; i++){
        int j = i-1;
        T temp = A[i];
        // 按升序排列
        while(j >= 0 && A[j] > temp){
            A[j+1] = A[j];
            j--;
        }
        A[j+1] = temp;
    }
}

(2)冒泡排序

冒泡排序也是一个较简单的排序算法。冒泡排序通过不断交换两个元素实现,它的思想是:第一趟在序列(A[0]~A[n-1])中从前往后进行两个相邻元素的比较,若后者小,则交换,比较n-1次;第一趟排序结束,最大元素被交换到A[n-1]中(大的泡泡不断沉底),下一趟排序则只需在子序列(A[0]~A[n-2])中进行;如果在某一趟排序中未交换元素,说明子序列已经有序,则不再进行下一趟排序。冒泡排序算法的时间复杂度同样是O(n^2)。

template<typename T>
void bubbleSort(T *A, int length)
{
    int i, j, last;
    i = length-1;       //最多进行length-1次
    while(i > 0){
        last = 0;
        for(j = 0; j < i; j++){
            if(A[j] > A[j+1]){
                int tmp = A[j+1];
                A[j+1] = A[j];
                A[j] = tmp;
                last = j;       // 注意last的设置
            }
        }
        i = last;
    }
}

如上代码是通过last的设置来判断是否需要继续排序的。

(3)归并排序

归并排序是分治思想的应用,即不断将原问题划分为较小并较易解决的子问题,然后再合并子问题的结果得到原问题的结果。直观的操作如下:
A.分解:将n个元素分成各含n/2个元素的子序列;
B.解决:用合并排序法对两个子序列递归地排序;
C.合并:合并两个已排序的子序列以得到排序结果。
故归并排序的关键步骤在于合并两个已排序的子序列。为做排序,引入一个辅助过程MERGE(A,p,q,r),其中A是数组,p,q,r是下标,满足p<=q<r。该过程假设子数组A[p...q]和A[q+1...r]都已排好序,并将它们合并成一个已排好序的子数组代替当前子数组A[p...r]。
const int MaxInt = (1<<31)-1;
template<typename T>
void merge(T* A, int p, int q, int r)
{
    int length1 = q-p+1;
    int length2 = r-q;
    // 多出的一个空间用来放置哨兵
    int *L = new int[length1+1];
    int *R = new int[length2+1];
    // 把原先数组的值分别复制到左边和右边
    for(int i = 0; i < length1; i++)
        L[i] = A[p+i];
    for(int i = 0; i < length2; i++)
        R[i] = A[q+1+i];
    L[length1] = R[length2] = MaxInt;
    // 开始合并
    int i = 0, j = 0;
    for(int k = p; k <= r; k++){
        if(L[i] < R[j])
            A[k] = L[i++];
        else
            A[k] = R[j++];
    }
    // 记得回收内存
    delete []L;
    delete []R;
}
template<class T>
void mergeSort(T* A, int p, int r)
{
    if(p < r){
        // 说明数组至少还有2个元素,要继续排序
        int q = (p+r)/2;
        mergeSort(A, p, q);
        mergeSort(A, q+1, r);
        merge(A, p, q, r);

    }
}

这个排序算法实现起来虽然比前两个算法复杂,但效率也高很多,归并排序的时间复杂度是O(nlgn)。



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值