qsort详细实现, 双向冒泡

来源:互联网 发布:rax户外鞋怎么样知乎 编辑:程序博客网 时间:2024/04/29 03:59
高级排序算法中我们将只介绍这一种,同时也是目前我所知道(我看过的资料中)的最快的。它的工作看起来仍然象一个二叉树。首先我们选择一个中间值middle程序中我们使用数组中间值,然后把比它小的放在左边,大的放在右边(具体的实现是从两边找,找到一对后交换)。然后对两边分别使用这个过程(最容易的方法——递归)。

1.快速排序:

#include <iostream.h>void run(int* pData,int left,int right){    int i,j;    int middle,iTemp;    i = left;    j = right;    middle = pData[(left+right)/2];  //求中间值    do{        while((pData[i]<middle) && (i<right))//从左扫描大于中值的数            i++;                  while((pData[j]>middle) && (j>left))//从右扫描大于中值的数            j--;        if(i<=j)//找到了一对值        {            //交换            iTemp = pData[i];            pData[i] = pData[j];            pData[j] = iTemp;            i++;            j--;        }    }while(i<=j);//如果两边扫描的下标交错,就停止(完成一次)    //当左边部分有值(left<j),递归左半边    if(left<j)        run(pData,left,j);    //当右边部分有值(right>i),递归右半边    if(right>i)        run(pData,i,right);}void QuickSort(int* pData,int Count){    run(pData,0,Count-1);}void main(){    int data[] = {10,9,8,7,6,5,4};    QuickSort(data,7);    for (int i=0;i<7;i++)        cout<<data[i]<<" ";    cout<<"\n";}


这里我没有给出行为的分析,因为这个很简单,我们直接来分析算法:首先我们考虑最理想的情况
1.数组的大小是2的幂,这样分下去始终可以被2整除。假设为2的k次方,即k=log2(n)。
2.每次我们选择的值刚好是中间值,这样,数组才可以被等分。
第一层递归,循环n次,第二层循环2*(n/2)......
所以共有n+2(n/2)+4(n/4)+...+n*(n/n) = n+n+n+...+n=k*n=log2(n)*n
所以算法复杂度为O(log2(n)*n)
其他的情况只会比这种情况差,最差的情况是每次选择到的middle都是最小值或最大值,那么他将变成交换法(由于使用了递归,情况更糟)。但是你认为这种情况发生的几率有多大??呵呵,你完全不必担心这个问题。实践证明,大多数的情况,快速排序总是最好的。
如果你担心这个问题,你可以使用堆排序,这是一种稳定的O(log2(n)*n)算法,但是通常情况下速度要慢于快速排序(因为要重组堆)。三、其他排序
1.双向冒泡:
通常的冒泡是单向的,而这里是双向的,也就是说还要进行反向的工作。
代码看起来复杂,仔细理一下就明白了,是一个来回震荡的方式。
写这段代码的作者认为这样可以在冒泡的基础上减少一些交换(我不这么认为,也许我错了)。
反正我认为这是一段有趣的代码,值得一看。
#include <iostream.h>void Bubble2Sort(int* pData,int Count){    int iTemp;    int left = 1;    int right =Count -1;    int t;    do    {        //正向的部分        for(int i=right;i>=left;i--)        {            if(pData[i]<pData[i-1])            {                iTemp = pData[i];                pData[i] = pData[i-1];                pData[i-1] = iTemp;                t = i;            }        }        left = t+1;        //反向的部分        for(i=left;i<right+1;i++)        {            if(pData[i]<pData[i-1])            {                iTemp = pData[i];                pData[i] = pData[i-1];                pData[i-1] = iTemp;                t = i;            }        }        right = t-1;    }while(left<=right);}void main(){    int data[] = {10,9,8,7,6,5,4};    Bubble2Sort(data,7);    for (int i=0;i<7;i++)        cout<<data[i]<<" ";    cout<<"\n";}快速排序#include <iostream> using namespace std; class QuickSort { public:     void quick_sort(int* x,int low,int high)     {         int pivotkey;         if(low <high)         {             pivotkey=partion(x,low,high);             quick_sort(x,low,pivotkey-1);             quick_sort(x,pivotkey+1,high);         }     }     int partion(int* x,int low,int high)     {         int pivotkey;         pivotkey=x[low];         while(low <high)         {             while (low <high&&x[high]>=pivotkey)                 --high; //还有while循环只执行这一句            x[low]=x[high];             while (low <high&&x[low] <=pivotkey)                 ++low; //还有while循环只执行这一句            x[high]=x[low];         }         x[low]=pivotkey;         return low;     } }; int main() {     int x[10]={52,49,80,36,14,58,61,97,23,65};     QuickSort qs;     qs.quick_sort(x,0,9);     cout <<"排好序的数字序列为:" <<endl;     for (int i=0;i <10;i++)     {       printf("%d ",x[i]);     } return 0; }

原创粉丝点击