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

来源:互联网 发布:淘宝店铺新品上架 编辑:程序博客网 时间:2024/06/14 18:20

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

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)。

原创粉丝点击