所有排序总结(内排序)
花时间把所有的排序重新 写了一遍。。。。。(应该是认真写过一遍,学的时候根本就没写过)
写得时候才发现,理解不深刻。基本上 只是懂怎么做,不懂为什么。
把我写得记在这里,以后用得着了回来看看。
暂时就到这里吧,以后有时间,继续研究这些东西。在写出来。
三个O(n 2 )的算法
选择排序:
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和测试的代码 我就没贴了
作者: Leo_wl
出处: http://www.cnblogs.com/Leo_wl/
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
版权信息声明:本文来自网络,不代表【好得很程序员自学网】立场,转载请注明出处:http://haodehen.cn/did48285