原地归并排序

转自:http://www.cnblogs.com/daniagger/archive/2012/07/25/2608373.html

不需要辅助数组即可归并。

关键在于merge这个函数。两段递增的子数组arr[begin…mid-1]和arr[mid…end],i=begin,j=mid,k=end

image

 

i往后移动,找到第一个arr[i]>arr[j]的索引

image

j往后移动,再找第一个arr[j]>arr[i]的索引

image

然后我们将i到mid的部分和mid到j-1的部分对调,较小的部分就调到前面去了,然后从后面的部分与j到k的部分又是两个递增的子数组,继续迭代即可。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
#include <iostream>
using  namespace  std;
 
//交换两个数
void  swap( int  *a, int  *b)
{
     int  temp=*a;
     *a=*b;
     *b=temp;
}
 
//将长度为n的数组逆序
void  reverse( int  *arr, int  n)
{
     int  i=0,j=n-1;
     while (i<j)
     {
         swap(arr[i],arr[j]);
         i++;
         j--;
     }
}
 
//将数组向左循环移位i个位置
void  exchange( int  *arr, int  n, int  i)
{
     reverse(arr,i);
     reverse(arr+i,n-i);
     reverse(arr,n);
}
 
//数组两个有序部分的归并
void  merge( int  *arr, int  begin, int  mid, int  end)
{
     int  i=begin,j=mid,k=end;
     while (i<j && j<=k)
     {
         int  step=0;
         while (i<j && arr[i]<=arr[j])
             ++i;
         while (j<=k && arr[j]<=arr[i])
         {
             ++j;
             ++step;
         }
         exchange(arr+i,j-i,j-i-step);
         i=i+step;
     }
}
 
void  MergeSort( int  *arr, int  l, int  r)
{
     if (l<r)
     {
         int  mid=(l+r)/2;
         MergeSort(arr,l,mid);
         MergeSort(arr,mid+1,r);
         merge(arr,l,mid+1,r);
     }
}
 
int  main()
{
     int  arr[]={6,4,3,1,7,8,2,9,5,0};
     int  len= sizeof (arr)/ sizeof (arr[0]);
     MergeSort(arr,0,len-1);
     for ( int  i=0;i<len;++i)
         cout <<arr[i]<< " " ;
     cout <<endl;
     return  0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值