所有排序总结(内排序)

花时间把所有的排序重新 写了一遍。。。。。(应该是认真写过一遍,学的时候根本就没写过)

     写得时候才发现,理解不深刻。基本上 只是懂怎么做,不懂为什么。

     把我写得记在这里,以后用得着了回来看看。

     暂时就到这里吧,以后有时间,继续研究这些东西。在写出来。

三个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和测试的代码   我就没贴了

posted @ 2012-08-08 15:36  细胞核  阅读(1983)  评论(5编辑  收藏  举报