归并算法很有意思哈!它可以指定开始位置和结束位置,只对其中的某一段进行排序,它的定义是把两个或两个以上的有序表组合成一个新的序表,这种方法我们称它二路归并排序,他的算法实现也是很奇妙的,接下来看一下代码吧!
#include<iostream>
using namespace std;
int *p=new int[100]; //为合并两段的元素做一个备份数组
void mer(int h[], int a, int b, int c) { //a代表第一段的头,b代表第一段的尾,c代表第二段的尾
int i, j, k;
for (i= a; i <= c; i++)
{
p[i] = h[i]; //将元素做备份
}
for (i = a,j=b+1,k=i; i <=b && j <= c; k++) //第一段或第二段其中一个元素遍历完成结束循环
{
if (p[i] <= p[j]) //第一段的第一个和第二段的第一个进行比较,存入更小的那一个
h[k] = p[i++];
else
h[k] = p[j++];
}
while (i<=b) //最后肯定有其中一段还有数据没有存入,依次存入
{
h[k++] = p[i++];
}
while (j<=c)
{
h[k++] = p[j++];
}
}
void mer1(int h[], int a, int c) {
int b;
if (a < c) {
b = (a + c) / 2; //一分二,b指向第一段的最后一个元素
mer1(h, a, b);
mer1(h, b+1, c); //在这里使用递归不断地进行一分二操作
mer(h, a, b, c); /*调用合并函数,第一次真正调用这个函数
一定是最里层的递归,也就是两个数的合并操作*/
}
}
int main() {
int h[100];
for (int i = 0; i < 10; i++)
{
cin >> h[i];
}
mer1(h, 2, 9); //这里传进去一个头一个尾,意思是只对从第三个数开始到第十个数进行排序;
for (int i = 0; i < 10; i++)
{
cout << h[i]<<" ";
}
system("pause");
return 0;
}
最难理解的应该就是这个递归的实现了,前面的合并方法可根据注释手动在纸上演算一下就会明白,这里的递归呢其实是一分二,二分四,四分八的这么一个思想,最里层的肯定是分的不可以再分了,也就是只剩下两个元素的时候,之后逐层合并退出,当退出来最开始的时候就可以对最后的两个大序列进行排序的,还是很神奇的哈!算法真的很奇妙,当你接触的越多越深的时候你会发现这里面的智慧是令人惊讶的。