风致 发表于 2007-9-23 20:05

呵呵,发现了超全的排序代码!!和大家分享!

<P><STRONG>关于排序的认识<BR>排序总的可以分为插入排序,交换排序,选择排序,归并排序,基数排序等。</STRONG></P>
<P><STRONG>其中插入排序又可以细分为直接插入排序,折半排序,希尔排序。<BR>直接排序的基本思想是:当插入第i (i&gt;=1)个对象时,前面的v[0],v[1],…….v[i-1]已经排好序,这时,用v[i]的关键码与v[i-1],v[i-2]……的关键码顺序进行比较,找到插入位置即将v[i]插入,原来位置上的对象向后顺移。直接插入排序的时间复杂度为n2,直接插入排序是一种稳定的排序方法。<BR>折半排序的基本思想是:设在顺序表中有一个对象序列v[0],v[1],….v[n-1],其中,v[0],v[1],….v[i-1]是已经排好序的对象。在插入v[i]时,利用折半查找法寻找v[i]的插入位置。折半插入是一种稳定的排序方法。<BR>希尔排序:当待排序的数列很长时,(即n很大时),关键码平均比较次数和对象平均移动次数大约在n1.25(即n的1.25次方,以下同样)到1.6n1.25范围内。</STRONG></P>
<P><STRONG>交换排序又可细分为冒泡排序,快速排序。<BR>冒泡排序的基本思想是:设待排序的数列的大小为n,首先比较v[n-2]和v[n-1]的大小,如果v[n-2]&gt;v[n-1],则交换v[n-2]和v[n-1],然后对v[n-2]和v[n-3]作相同的处理,如此处理, 直到处理完v[0]和v[1],这个称为一趟冒泡,所以只要经过n-1 趟冒泡就可以排好所有对象。    在最坏情况下总的关键码比较次数为0.5n(n-1),对象移动次数为1.5n(n-1)<BR>快速排序的基本思想是:取待排序的数列的某个对象(例如第一个对象)作为基准,将对象分为左右两个数列,左边的全都小于基准,右边的全都大于基准,然后对左右两个树列重复以上操作,直到全部完成。它是一种不稳定的方法,对于待排序的数列很大时,快速排序的确很快,但当待排序的数列很小时,它往往比其它简单的排序方法还要慢。</STRONG></P>
<P><STRONG>选择排序又可以细分为直接选择排序,堆排序。<BR>直接选择排序的最坏情况是每一趟都要进行交换,总的对象移动次数是3(n-1)。<BR>堆排序可以分为两个步骤:首先,根据初始输入数据,利用堆的调整算法FilterDown()形成初始堆, 第二步通过一系列的对象交换和重新调整堆进行排序。堆排序的是一个不稳定的排序方法,并且当待排序的数列很大时,堆排序不可取。</STRONG></P>
<P><STRONG>归并排序就是将两个或两个以上的有序表合并成一个新的有序表。</STRONG></P>
<P><STRONG>基数排序的基本思想是:待排序的对象按m个关键码key[0],…..key[m-1]排序,每个对象的关键码域用一个数组key[m]表示,对各关键码的排序采用箱排序。</STRONG></P>
<P><STRONG>从上面可以得出结论(本人观点),当待排序的数列很小时,可以采取直接插入排序,折半排序,希尔排序,直接选择排序,堆排序,归并排序,基数排序等众多排序方法,但当待排序的数列很大时,采用快速排序为优。</STRONG></P>
<P><STRONG>就平均性能而言,我认为快速排序最好。<BR>冒泡排序:<BR>void CSortDlg::bubble_sort(int x[]){<BR>    //对数组x[]逐趟进行比较 ,遇到逆序即交换<BR>        int i =1;int exchange=1;//当exchange为0时,则停止排序<BR>        while((i&lt;10 )&amp;&amp;exchange){//<BR>            BubbleExchange( x, i, exchange);<BR>            i++;<BR>                    }<BR>    }<BR>void CSortDlg::BubbleExchange(int x[],int i,int exchange){<BR>        exchange = 0;//假定元素未交换<BR>        for(int j =9;j&gt;=i;j--){<BR>                    if(x[j-1]&gt;x[j])//发生了逆序<BR>            {<BR>                        int    temp = x[j-1];//交换<BR>            x[j-1]=x[j];<BR>            x[j] = temp;<BR>              exchange = 1;//做“发生了交换”的标志<BR>                    }<BR>            }<BR>}<BR>直接插入排序:<BR>void CSortDlg::InsertionSort(int x[])<BR>{<BR>    for(int i=1;i&lt;10;i++)<BR>    {<BR>        Insert(x,i);<BR>    }<BR>}<BR>void CSortDlg::Insert(int x[],int i)<BR>{<BR>    int temp=x[i]; int j=i;<BR>    while (j&gt;0&amp;&amp;temp&lt;x[j-1]) <BR>    {<BR>        x[j]=x[j-1];<BR>        j--;<BR>    }<BR>    x[j]=temp;<BR>}<BR>希尔排序:<BR>void CSortDlg::Shellsort(int x[])<BR>{<BR>    int gap=10/2;//增量的初始值<BR>    while (gap)//循环条件是gap&gt;=1<BR>    {<BR>        ShellInsert(x,gap);//按增量gap划分子序列,分别进行插入排序<BR>        gap=gap==2?1:(int)(gap/2);//缩小增量gap<BR>    }<BR>}<BR>void CSortDlg::ShellInsert(int x[],const int gap)<BR>{<BR>    for(int i=gap;i&lt;10;i++)//各子序列轮流执行插入排序<BR>    {<BR>        int temp=x[i];int j=i;//暂存待插入对象<BR>        while (j&gt;=gap&amp;&amp;temp&lt;x[j-gap]) {//当前插入元素比位于j-gap的元素小,则位于j-gap的元<BR>                                //素后移<BR>            x[j]=x[j-gap];<BR>                j-=gap;//后移到第j个位置,j指标前指<BR>        }<BR>        x[j]=temp;//插入<BR>    }<BR>}<BR>归并排序:<BR>void CSortDlg::MergeSort(int x[])<BR>{<BR>    int temp_array[10];<BR>    int len=1;<BR>    while (len&lt;10) {    //归并排序<BR>        MergePass(x,temp_array,len);//一趟两路归并后归并项长度加倍<BR>        len*=2;<BR>        MergePass(temp_array,x,len);<BR>        len*=2;<BR>    }<BR>//    delete[] temp_array;<BR>}<BR>void CSortDlg::MergePass(int init_array[],int merge_array[],const int len)<BR>{//一趟归并排序<BR>    int i=0;<BR>    while (i+2*len&lt;=9) {//对长度为len的子表两两归并,直到表中剩余元素个数不足2*len为止<BR>        merge(init_array,merge_array,i,i+len-1,i+2*len-1);<BR>        i+=2*len;<BR>    }<BR>    if (i+len&lt;=9)<BR>            merge(init_array,merge_array,i,i+len-1,9);            else                        <BR>            for (int j=i;j&lt;=9;j++) {//若不能做归并,就复制<BR>                merge_array[j]=init_array[j];<BR>            }<BR>                }<BR>void CSortDlg::merge(int init_array[],int merge_array[],const int l,const int m,const int n)<BR>{<BR>       int i=l,j=m+1,k=l;<BR>       while (i&lt;=m&amp;&amp;j&lt;=n) <BR>           if (init_array[i]&lt;=init_array[j]) {<BR>               merge_array[k]=init_array[i];<BR>               i++;k++;<BR>           }<BR>           else<BR>           {<BR>               merge_array[k]=init_array[j];<BR>               j++;k++;<BR>           }   <BR>           if (i&lt;=m) <BR>               for (int n1=k,n2=i;n1&lt;=n&amp;&amp;n2&lt;=m;n1++,n2++) {<BR>                   merge_array[n1]=init_array[n2];<BR>               }<BR>         else<BR>                   for (int n1=k, n2=j;n1&lt;=n&amp;&amp;n2&lt;=n;n1++,n2++) {<BR>                      merge_array[n1]= init_array[n2];<BR>                   }<BR>                }<BR>折半插入排序:<BR>void CSortDlg::BinaryInsertSort(int x[])<BR>{<BR>    for (int i=1;i&lt;10;i++) <BR>    {<BR>        BinaryInsert(x,i);<BR>    }<BR>}<BR>void CSortDlg::BinaryInsert(int x[],int i)<BR>{<BR>    int left=0,right=i-1;<BR>    int temp=x[i];<BR>    while (left&lt;=right) //利用折半查找找插入位置<BR>    {<BR>        int middle=(left+right)/2;//取中点<BR>        if (temp&lt;x[middle]) //插入值小于中点值<BR>        {<BR>            right=middle-1;//向左缩小区间<BR>        }<BR>        else            //否则向右缩小区间<BR>            left=middle+1;<BR>    }<BR>    for (int k=i-1;k&gt;=left;k--)//成块移动,空出插入位置<BR>    {<BR>        x[k+1]=x[k];<BR>    }<BR>    x[align=left]=temp;//插入<BR>}<BR>直接选择排序:<BR>void CSortDlg::SelectSort(int x[])<BR>{<BR>    for (int i=0;i&lt;9;i++) {<BR>        SelectExchange(x,i);<BR>    }<BR>}<BR>void CSortDlg::SelectExchange(int x[],const int i)<BR>{<BR>    int k=i;<BR>    for (int j=i+1;j&lt;10;j++) <BR>        if(x[j]&lt;x[k])<BR>            k=j;<BR>    if(k!=i)<BR>    {<BR>        int temp=x[i];<BR>        x[i]=x[k];<BR>        x[k]=temp;<BR>    }<BR>}<BR>基数排序:<BR>int CSortDlg::digit(int data,int n)<BR>{<BR>          int i = -1;<BR>       for (int k = 0; k &lt;= n;++k)<BR>       {<BR>              i = data % RADIX;<BR>              data = data / RADIX;<BR>       }<BR>       return i;<BR>}<BR>void CSortDlg::SortOnDigit(int* data,int d,int left,int right)<BR>{<BR>           int c[RADIX] = {0};  //c[i]记录d位上为i的元素个数<BR>       for (int i = left; i &lt;= right ;i++ )<BR>       {<BR>              ++c[digit(data[i],d)];  //记录d位上相同的数据个数<BR>       }<BR>       for (int j = 1;j &lt; RADIX ;++j )<BR>       {<BR>              c[j] += c[j-1];         //很明显,d位上较大(就是j的值),元素越大<BR>                                     //c[j]记录d位上小于等于j的元素的个数<BR>       }<BR>       int len = right - left +1;<BR>       int* tmp = new int[len];<BR>       //知道了有多少元素在d位置上比自己小,则可以确定d位上的值的元素位置<BR>       for (int k = right; k &gt;= left; k--)<BR>       {<BR>              tmp[--c[digit(data[k],d)]] = data[k];<BR>       }<BR>       for (int m = left;m &lt;= right ;++m )<BR>       {<BR>              data[m] = tmp[m - left];<BR>      }<BR>       delete[] tmp;<BR>}<BR>void CSortDlg::RadixSort(int* data,int left,int right)<BR>{<BR>    for (int i = 0;i &lt; WIDTH; ++i)<BR>       {<BR>              SortOnDigit(data,i,left,right);<BR>       }<BR>}<BR>快速排序:<BR>void CSortDlg::quick_sort(int x[], int low, int high)   //快速排序函数的实现过程 <BR>{ </STRONG></P>
<P><STRONG>     int pivotkey;<BR>         if(low&lt;high)<BR>      {<BR>        pivotkey=partition(x,low,high);<BR>          quick_sort(x,low,pivotkey-1);<BR>           quick_sort(x,pivotkey+1,high);<BR>       }<BR>} <BR>int CSortDlg::partition(int x[],int low,int high)<BR>{<BR>  int pivotkey;<BR>  pivotkey=x[low];<BR>    while(low&lt;high)<BR>   {<BR>     while(low&lt;high&amp;&amp;x[high]&gt;pivotkey)<BR>               --high;<BR>            x[low]=x[high];<BR>      while(low&lt;high&amp;&amp;x[low]&lt;pivotkey)<BR>               ++low;<BR>            x[high]=x[low];<BR>    }<BR> //     x[low]=x[0];<BR>      x[low]=pivotkey;<BR>      return low;<BR>}<BR>堆排序:<BR>void CSortDlg::HeapSort(int*list,int num)<BR>{<BR>    for(int i=(num-2)/2;i&gt;=0;i--)<BR>        FiltDown(list,i,num-1);<BR>    for(i=num-1;i&gt;=1;i--)<BR>    {<BR>        int temps=list[0];<BR>        list[0]=list[i];<BR>        list[i]=temps;<BR>        FiltDown(list,0,i-1);<BR>//        if(m_mark==1)<BR>//        show(list);<BR>    }<BR>}<BR>void CSortDlg::FiltDown(int*list,int i,int end)<BR>{<BR>    int c=i;int ch=2*i+1;<BR>    int temp=list[i];<BR>    while(ch&lt;=end)<BR>    {<BR>        if(ch&lt;end&amp;&amp;list[ch]&lt;list[ch+1])<BR>            ch++;<BR>        if(temp&gt;=list[ch])break;<BR>        else<BR>        {<BR>            list[c]=list[ch];<BR>            c=ch;ch=2*ch+1;<BR>        }<BR>    }<BR>    list[c]=temp;<BR>}<BR>                            <BR><BR>                                          <BR><BR></P></STRONG>

鹏云翅 发表于 2007-9-24 02:02

<P>收藏一下</P>
[align=right][color=#000066][此贴子已经被作者于2007-9-24 2:03:33编辑过][/color][/align]


页: [1]

编程论坛