新手讲排序:归并排序

归并排序给我的感觉:编程一定要认真,不然就算你能想通也要纠缠你很长时间

(1)本质:

    1.分解:用二分法,每次将数组分成两个元素数量相同或者差一个(奇数)的子数组,然后递归直到将子数组分成一个一个的元素,实际数组不用分,你直接将它看成已经分好的元素

    2.合并:将len=1的数组合并成len=2的数组,合并的时候通过将两个数组的元素按大小插入到临时数组,再将临时数组元素赋予原数组,所以我们得到从len=1到len=len/2的每一个数组都是有序的

(2)例子: 10个元素的例子

    1.   10,8,9,2,5,4,6,3,7,1(直接看成拆分之后的数据)

           2.第一次合并 8,10   2,9    4,5    3,6    1,7

           3.第二次合并  2,8,9,10     3,4,5,6     1,7

           4.第四次合并   2,3,4,5,6,8,9,10   1,7

           5.第五次合并  1,2,3,4,5,6,7,8,9,10

(3)代码:

 1 #include<iostream>
 2  using namespace std;
 3  //这个逻辑比较简单,两个数组都有序,通过将他们插入到临时数组来合并 
 4  void merge(int *a,int low,int mid,int high){
 5      int i=low,j=mid+1,num=0;
 6      int temp[high-low+1];
 7      memset(temp,0,sizeof(temp));
 8      while(i<=mid&&j<=high){
 9          if(a[i]<=a[j]) temp[num++]=a[i++];
10          else  temp[num++]=a[j++];
11      }
12      while(i<=mid) temp[num++]=a[i++];
13      while(j<=high) temp[num++]=a[j++];
14      for(i=0;i<high-low+1;i++){
15          a[i+low]=temp[i];
16      }
17      
18  } 
19  void merge_pass(int *a,int gap,int length){
20     int i=0;
21     //合并长度为gap的两个区间 
22      for(i=0;i+2*gap-1<length;i+=2*gap){
23          merge(a,i,i+gap-1,i+2*gap-1);
24      }
25      //此时i+2*gap-1>length;此时的i-1<length ,则此时 剩下的两个区间i,i+gap-1,length-1 
26      //如果此时i+gap-1>=length ,说明此时最后剩一个区间了,那显然不用与任何其他区间合并 
27      if(i+gap-1<length-1){
28          merge(a,i,i+gap-1,length-1);
29      }
30  }
31  //上面是合并两个区间的,这里利用循环,将它最终合并成一个区间 
32  void merge_sort(int *a,int length){
33      for(int gap=1;gap<length;gap=2*gap)
34         merge_pass(a,gap,length);
35  } 
36  int main(){
37      int a[20];
38      int N,m,i,j;
39      cin>>N;
40      for(i=0;i<N;i++){
41          cin>>a[i];
42      }
43      merge_sort(a,N);
44      for(i=0;i<N;i++)
45              cout<<a[i]<<" ";
46      cout<<endl;
47      return 0;
48  } 
归并排序

 

posted @ 2015-09-07 11:21  jiguojing  阅读(234)  评论(0编辑  收藏  举报