排序算法二冒泡排序和快排

冒泡排序想必大家都非常熟悉了,这里就直接贴代码了

void BubbleSort(int array[],int len)
{
    assert(array && len>0 );


    for(int i = 0; i < len-1; ++i)
    {
        int flag = 1;
        for(int j = 0; j < len-1-i; ++j)
        {
            if(array[j] > array[j+1])
            {
                swap(array[j], array[j+1]);
                flag = 0;
            }
        }

            if(flag == 1)
                break;
    }
}

时间复杂度为O(N*N),最好的情况下:优化后正序有序为O(n),稳定的算法。
没有优化的与原始序列的状态无关,优化后与原始序列的状态有关

  • 快排
    挖坑法
    双指针法
//paration版本一:挖坑法
int Paration(int array[], int left, int right)
{
    int key = array[right];

    while(left < right)
    {
        while((left < right)&&(array[left] <= key) )
        {
            left++;
        }
        swap(array[left], array[right]);

        while((left < right) && (array[right] >= key))
        {
            right--;
        }
        swap(array[left], array[right]);
    }
    return left;
}

//paration版本二:双指针法
int Paration2(int array[], int left, int right)
{

    int key = array[right];
    int pcur = left;
    int pre = pcur-1;

    while(pcur <= right)
    {
        if((array[pcur] <= key) && (++pre != pcur) )
        {
            swap(array[pcur], array[pre]);
        }
        ++pcur;
    }
    return pre;
}

void QuickSort(int array[], int left ,int right)
{
    assert(array);

    if(left < right)
    {
        int index = Paration2(array, left ,right);
        QuickSort(array, left, index-1);
        QuickSort(array, index+1, right);
    }
}

非递归实现:


void QuickSort2(int array[], int left, int right)
{
    stack<int> s;

    s.push(right);
    s.push(left);

    while(!s.empty())
    {
        int left = s.top();
        s.pop();
        int right = s.top();
        s.pop();

        if(left < right) //防止下面插入index+1, inex-1越界。
        {
            int mid = (left+right)/2;
            int index = Paration2(array, left, right);

            s.push(right);
            s.push(index+1);

            s.push(index-1);
            s.push(left);
        }
    }
}

优化:
1)三数取中法
2)当区间已经划分到很小的时候可以改用插入排序
3)尾递归减少递归次数


//三数取中法,防止取到极端数据
int Middle(int array[], int left, int mid, int right)
{
    if(array[left] > array[right])
    {
        if(array[right] > array[mid])
            return right;
        else if(array[left] > array[mid])
            return mid;
        else
            return left;
    }
    else
    {
        if(array[right] < array[mid])
            return right;
        else if(array[left] < array[mid])
            return mid;
        else 
            return left;
    }
}

//paration版本二:双指针法
int Paration2(int array[], int left, int right)
{

    int mid = (left+right)/2;
    int pos = Middle(array, left, mid, right);
    swap(array[pos], array[right]);

    int key = array[right];
    int pcur = left;
    int pre = pcur-1;

    while(pcur <= right)
    {
        if((array[pcur] <= key) && (++pre != pcur) )
        {
            swap(array[pcur], array[pre]);
        }
        ++pcur;
    }
    return pre;
}

void InsertSort(int array[], int size)
{
    for(int i = 1; i < size; ++i)
    {
        int temp = array[i];
        int end = i-1;

        while(end>=0 && array[end] > temp)
        {
            array[end+1] = array[end];
            end--;
        }
        array[end+1] = temp;
    }
}

void QuickSort(int array[], int left ,int right)
{
    assert(array);


    while(right-left > 5)  //使用尾部递归
    {
        int index = Paration2(array, left ,right);
        QuickSort(array, left, index-1);
        left = index+1;
    }

    if(right-left <= 5)  //当分成很小的区间时,插入排序效率更高。
    {
        InsertSort(array+left, right-left+1);
    }
}

时间复杂度为O(n*lgn),最好情况为O(n*lgn),最坏情况O(n*n),因为递归空间复杂度O(lgn)
不稳定的算法
最坏的情况下:基本有序时,退化为冒泡排序,几乎要比较N*N次,故为O(N*N)
它的应用场景是大规模的数据排序
快速排序算法的实际执行性能依赖与切分是否均衡,当正好把数组从中间”切开”时,
快速排序的实际性能最好。
切分越不均衡快速排序的实际性能就越差,
最坏情况下(第一次选取的切分元素是数组里最小的,第二次的切分元素是第二小的…)
算法的时间复杂度会退化到O(n^2)。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值