所有排序總結(內排序)


花時間把所有的排序重新 寫了一遍。。。。。(應該是認真寫過一遍,學的時候根本就沒寫過)

     寫得時候才發現,理解不深刻。基本上 只是懂怎么做,不懂為什么。

     把我寫得記在這里,以后用得着了回來看看。

     暫時就到這里吧,以后有時間,繼續研究這些東西。在寫出來。

三個O(n2)的算法

選擇排序:

 1 void SelectionSort(int *a,int n)
 2 {
 3     for(int i=0;i<n;i++)
 4     {
 5         int lowindex = i;
 6         for(int j=i+1;j<n;j++)
 7            if(a[j]<a[lowindex])lowindex=j;
 8         swap(&a[i],&a[lowindex]);//選擇,比bubble交換次數少得多。
 9     }
10 }

冒泡排序:

1 void Bubblesort(int *a,int n)
2 {
3     for(int i=0;i<n;i++)
4       for(int j=0;j<n-1;j++)
5         if(a[j]>a[j+1])swap(&a[j],&a[j+1]);
6 }

插入排序:

 1 void insertsort(int *a,int n)
 2 {
 3     int i,j;
 4     int tmp;
 5     for(i = 1;i<n;i++)
 6     {
 7         tmp = a[i];
 8         for(j=i;j>0&&tmp<a[j-1];j--)
 9         {
10               a[j] = a[j-1];//從后往前面數
11         }
12         a[j] = tmp;//     1 2 3 5 6 7 4  ==>   1 2 3 4 5 6 7
13     }
14 }

 

下面幾個高級的算法。。。  有些把我折騰的夠慘。。。DEBUG 幾個小時 才弄出來。  (鄙視自己。。)

希爾排序:

 1 void shellsort(int *a,int n)
 2 {
 3     int tmp;
 4     int i,j;
 5     int gap;//增量
 6     for(gap=n/2;gap>0;gap/=2)//增量為n/2
 7     {
 8         for(i=gap;i<n;i++)
 9         {
10             tmp = a[i];
11             for(j =i;j>=gap&&tmp<a[j-gap];j-=gap)//增量交換。
12                 a[j] = a[j-gap];
13             a[j] = tmp;
14         }
15     }
16 }

歸並排序:

 1 void merge(int *array,int *tmp,int start,int center,int end)//合並的程序。
 2 {
 3     int i=0;
 4     int arrayCount = end - start + 1;
 5     int s = start;
 6     int c = center;
 7     int e = end;         //不損壞原來的變量
 8     while(s<=c-1&&c<=e)
 9     {
10         if(array[s]<=array[c])
11            tmp[i++] = array[s++];
12         else if(array[s]>=array[c])
13            tmp[i++] = array[c++];
14     }
15     while(s<=c-1)
16         tmp[i++] = array[s++];
17     while(c<=end)
18         tmp[i++] = array[c++];
19     for(i=start;i<arrayCount;i++)
20         array[i] = tmp[i-start];
21 }
22 void MergeSort(int *a,int *tmp,int start,int end)
23 {
24     int center;
25     if(start<end)
26     {
27         center = (start+end)/2 + 1;//第二個部分的開始
28         MergeSort(a,tmp,start,center-1);
29         MergeSort(a,tmp,center,end);
30         merge(a,tmp,start,center,end);
31     }
32 }

歸並的一個改進。。。。。改進不大   參照某本書上來的

 1 void merge(int *array,int *tmp,int start,int center,int end)//合並的程序。
 2 {
 3     //第二個子串逆序復制。    不用判斷是否處理完畢
 4    int i,j,k;
 5    for(i=start;i<center;i++)tmp[i]=array[i];
 6    for(j=0;j<end-center+1;j++)tmp[end-j] = array[center+j];
 7    for(i=start,j=end,k=start;k<=end;k++)
 8       if(tmp[i]<=tmp[j])array[k] = tmp[i++];
 9       else  array[k] = tmp[j--];
10 }//改進的部分

然后就是傳說中的快排了

快速排序 hoare版      參照某博文   july的快速排序分析。

 1 int HoarePartition(int *A,int p,int r)
 2 {
 3     int i,j,x;
 4     x = A[p];
 5     i = p-1;
 6     j = r+1;
 7     while(true)
 8     {
 9         do
10         {
11             j--;
12         }while(A[j]>x);//找到小於等於的
13         do
14         {
15             i++;
16         }while(A[i]<x);//找到大於等於的
17         if(i<j)
18            swap(&A[i],&A[j]);
19         else
20            return j;
21     }
22 }
23 /*      用do   while    的原因            */ 
24 /*如果data數組有相同元素就可能陷入死循環,比如:
25       2 3 4 5 6 2 
26   l->|             |<-h
27 
28 交換l和h單元后重新又回到:
29       2 3 4 5 6 2 
30   l->|             |<-h
31 
32 而第一個程序不存在這種情況,因為它總是在l和h調整后比較,也就是l終究會大於等於h。
33 */ 
34 void QuickSort(int *A,int p,int r)
35 {
36     int q;
37     if(p<r)
38     {
39         q = HoarePartition(A,p,r);
40         QuickSort(A,p,q);
41         QuickSort(A,q+1,r);
42     }
43 }

快速排序Hoare變形版

 1 int HoarePartition_1(int *A,int p,int r)
 2 {
 3     int i,j,x;
 4     x = A[p];
 5     i = p;
 6     j = r;
 7     while(i<j)
 8     {
 9         while(A[j]>=x&&i<j)j--;
10         A[i] = A[j];
11         while(A[i]<=x&&i<j)i++;
12         A[j] = A[i];
13     }
14     A[i] = x;
15     return i;
16 }
17 void QuickSort(int *A,int p,int r)
18 {
19     int q;
20     if(p<r)
21     {
22         q = HoarePartition_1(A,p,r);
23         QuickSort(A,p,q-1);
24         QuickSort(A,q+1,r);
25     }
26 }

快速排序  算法導論版

 1 int partition(int *A,int p,int r)
 2 {
 3     int i,j,x;
 4     x = A[r];
 5     i = p-1;
 6     for(j = p;j<r;j++)
 7     {
 8         if(A[j]<=x)
 9         {
10             i+=1;
11             swap(&A[i],&A[j]);
12         } 
13     }
14     swap(&A[i+1],&A[r]);
15     return i+1;
16 }
17 void quicksort(int *A,int p,int r)
18 {
19     if (p<r)
20     {
21         int q = partition(A,p,r);
22         quicksort(A,p,q-1);
23         quicksort(A,q+1,r);
24     }
25 }

啰嗦一句就是,快排 里面的partition  的返回值一定要搞明白。。。。。

這個幾個快速排序 都是參照 july 的博文來的。。。 感謝他。

 

最后  

堆排序:(莫名其妙 調試了很久。。。。。。)

 1 void buildmaxHeap(int *heap,int num)//建大頂堆   完全二叉樹數組存放
 2 {
 3     int leftchild,rightchild;
 4     int maxchild;
 5     for(int i=num/2-1;i>=0;i--)
 6     {
 7         leftchild = 2*i+1;//子節點  根節點 從0開始
 8         rightchild =2*i+2;
 9         if(leftchild<num && rightchild>=num)
10            maxchild = leftchild;
11         else if(leftchild>=num)
12            maxchild = i;//不存在這種情況
13         else if(rightchild<num)
14         {
15             if( heap[leftchild]<=heap[rightchild] )
16                maxchild = rightchild;
17             else if(heap[leftchild]>heap[rightchild])
18                maxchild = leftchild;
19         }
20 
21         if(heap[i]<heap[maxchild])
22            swap(&heap[i],&heap[maxchild]);
23     }
24 }
25 void HeapSort(int *heap,int n)
26 {
27     for(int i=n;i>0;i--)
28     {
29         buildmaxHeap(heap,i);
30         swap(&heap[0],&heap[i-1]);//最大的值交換到最后面
31     }
32 }

 

恩,歸並的遞歸  堆排序   都糾結了較長時間

         有時間,我還要把遞歸好好看一看。。。。。

 

注:這上面的swap和測試的代碼   我就沒貼了


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM