这个就是归并算法的思维,其中主要运用了分治算法。
归并分为“归”和“并”
并:
void Bing(int brr[], int left, int mid, int right)
{
int i = left;
int j = mid + 1;
int aux[12];
for (int m = left; m <= right; m++)//这里必须要用aux[m-left],因为left不一定是0,而aux数组的赋值必须从0开始
{
aux[m - left] = brr[m];
}
for (int m = left; m <= right; m++)
{
if (j > right)
{
brr[m] = aux[i-left];
i++;
}
else if (i > mid)
{
brr[m] = aux[j-left];
j++;
}
else if (aux[i-left] > aux[j-left])
{
brr[m] = aux[j-left];
j++;
}
else
{
brr[m] = aux[i-left];
i++;
}
}
}
其中,用mid分割成两个数组,然后left和mid+1表示两个数组的头,也就是i和j。
先不考虑边界情况,如果两个数组比如:
80 30 60 20
10 60 50 70
先是80和10比,此时i指向80,j指向10,10比较小,所以把10放入数组中,然后j++,让j指向60,继续比较
这样下来,如果遇到了i>mid,那么就说明第一个数组都被放放进去了,那么后来就是把第二个数组依次放进去就行了。当j>right的情况也是一样的
注意:所有的数组下标都要减去left,因为left不一定为零
“归”:
void Gui(int arr[], int left, int right)
{
if (left >= right)
return;
int mid = (left + right) / 2;
Gui(arr, left, mid);
Gui(arr, mid + 1, right);
Bing(arr, left, mid, right);
}
这里用了递归的方法,请结合上面的图来理解可能会更好理解
最后给上代码:
#include<iostream>
using namespace std;
int brr[10];
void Bing(int brr[], int left, int mid, int right)
{
int i = left;
int j = mid+1;
int aux[12];
for (int m = left; m <= right; m++)
{
aux[m - left] = brr[m];
}
for (int m = left; m <= right; m++)
{
if (j > right)
{
brr[m] = aux[i-left];
i++;
}
else if (i > mid)
{
brr[m] = aux[j-left];
j++;
}
else if (aux[i-left] > aux[j-left])
{
brr[m] = aux[j-left];
j++;
}
else
{
brr[m] = aux[i-left];
i++;
}
}
}
void Gui(int arr[], int left, int right)
{
if (left >= right)
return;
int mid = (left + right) / 2;
Gui(arr, left, mid);
Gui(arr, mid + 1, right);
Bing(arr, left, mid, right);
}
int main()
{
int n;
int crr[10];
cin >> n;
for (int i = 0; i < n; i++)
{
cin >> crr[i];
}
Gui(crr, 0, n - 1);
for (int i = 0; i < n; i++)
{
cout << crr[i];
}
system("pause");
return 0;
}