花時間把所有的排序重新 寫了一遍。。。。。(應該是認真寫過一遍,學的時候根本就沒寫過)
寫得時候才發現,理解不深刻。基本上 只是懂怎么做,不懂為什么。
把我寫得記在這里,以后用得着了回來看看。
暫時就到這里吧,以后有時間,繼續研究這些東西。在寫出來。
三個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和測試的代碼 我就沒貼了
