(一)冒泡排序,插入排序,选择排序

统一接口:

template <class T>
void sort(int lo, int hi)
{
    switch (rand()%3) {
        case 1:
            BubbleSort(lo,hi); break;
        case 2:
            SelectSort(lo,hi) break;
        case 3:
            InsertSort(lo,hi) break;
    }
}

A冒泡排序 改进版
比较相邻的元素。如果第一个比第二个大,就交换他们两个。
对每一对相邻元素作同样的工作,从开始第一对到结尾的最后一对。这步做完后,最后的元素会是最大的数。
改进版:
每次遍历检同时查是否有序,如果有序直接跳出循环来提高效率

typedef int Rank;
int _elem[];
bool bubble(Rank lo,Rank hi){
    bool sorted = true; //标志整体有序
    while(++lo < hi){
        if(_elem[lo-1] > _elem[lo])
        {
            sorted = false;
            swap(_elem[lo-1],_elem[lo]);
        }
    }
    return sorted;
}
void BubbleSort(Rank lo,Rank hi){
    while(!bubble(lo, hi--));
}

B冒泡排序 再改进
每次遍历时候记录最后一次交换的秩,可以发现在这个秩后面的元素都没有发生交换,这说明在这个秩后的元素已经满足有序的条件,可以提前跳出这次遍历。

Rank bubble(Rank lo,Rank hi){
    Rank last = lo; //初始化last
    while(++lo < hi){
        if(_elem[lo-1] > _elem[lo])
        {
            last =lo;
            swap(_elem[lo-1],_elem[lo]);
        }
    }
    return last; //返回右侧逆序对的位置
}
void BubbleSort(Rank lo,Rank hi){
    while(lo<(hi=bubble(lo, hi)));
}

A插入排序
它的工作原理是通过构建有序序列,对于未排序数据,在已排序序列中从后向前扫描,找到相应位置并插入。
因而在从后向前扫描过程中,需要反复把已排序元素逐步向后挪位,为最新元素提供插入空间。
这里写图片描述

template<typename T>
void InsertSort(T arr[], int len) {
    T temp;
    for (int i = 1; i < len; i++) {
        temp = arr[i];
        int j;
        for (j = i - 1; j >= 0 && arr[j] > temp; j--)//从temp的位置向前逐个比较,找到第一个小于等于temp的;否则就将那个数向后移动
            arr[j + 1] = arr[j];
        arr[j + 1] = temp; //将找到的第一个满足条件的位置后面放上temp
    }
}
//这里提供另一种写法:
int a[]={4,0,2,3,1},i,j,t;
for(i=1;i<5;i++){
    t=a[i];
    j=i-1;
    while(j>=0&&t>a[j]){
        a[j+1]=a[j];
        --j;
    }
    a[j+1]=t;
}

A选择排序
原理
首先在未排序序列中找到最小(大)元素,与起始位置交换,然后,再从剩余未排序元素中继续寻找最小(大)元素,与当前起始位置交换。以此类推。
这里写图片描述

template<typename T>
void SelectSort(T a[], int len) {
    int min;
    for (int i = 0; i < len - 1; i++) {
        min = i;
        for (int j = i + 1; j < len; j++)//从[i+i,len)区间中找到最小值
            if (a[min] > a[j])
                min = j;
        swap(arr[i], arr[min]);//将在[i+1,len)找到的最小值于a[i]交换
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值