一:主要思想
将若干个有序序列逐步归并,最终合成一个有序队列
二:问题
1:怎样构造初始有序队列
2:两个相邻的队列如何合成一个有序队列
3:怎样完成一趟和合并(二种我们只完成了前面相邻的)
4:完成归并结束的标志是什么
三:问题的解决
1:初始长度为1的有序序列
2:相邻数组中按照大小依次放到暂存数组
/**
* 1:我们将代排序列看成长度为1的n个有序序列 2:两个相邻的如何合并成一个有序序列 s:第一个数列第一个位置 m:第一个数列最后一个位置
* t:第二个数列某位置 k:合并之后队列的首位置
*
* 我们传的是原数组,暂存数组,有序队列第一位置,最后一个位置,有序队列第二个末位置
*/
public void merge(int r[], int r1[], int s, int m, int t) {
int i, j, k;
i = s;
j = m + 1;
k = s;
while (i < m && j < t)
{
if (r[i] < r[j])
r1[k++] = r[k++];
else
r1[k++] = r[j++];
}
// 第一个没处理完或者第二个,没处理完
if (i < m) {
while (i < m)
r1[k++] = r[i];
} else {
// 第二个数组,没处理完
while (j < t)
r1[k++] = r[j++];
}
}
三:怎么样把剩下的一趟合并
3.1:我们分三种情况
1:合并的全是前面的
2:合并到末尾
2.1:剩一个长度小于h的和长度为h的
2.2:只剩下一个长度为h的
public void MergePass(int r[], int r1[], int n, int h) {
int i = 1;
/**
* 1:合并两个长度都为h; 2:合并一个H,另一个小于h(末尾情况) 3:合并自剩下一个h,我们把它挂在合并之后的数组中
*/
// 1:合并长度都为h的有序序列
while (i < n - 2 * h + 1) {
// 看1是否减掉,我们看i是否包含里面
merge(r, r1, i, i + h - 1, i + 2 * h - 1);
// i的值后移2h未
i += 2 * h;
}
// 2:合并到最后后剩一个长度小于h,和一个长度为h的数组
if (i < n - h + 1) {
merge(r, r1, i, i + h - 1, n);
} else {
for (int k = i; k < n; k++) {
r1[k] = r[k];
}
}
}
四: 结束标志
初始长度为1,我们判断最后队列长度是否为n,作为结束标志
/**
*判断结束
*/
public void MergeSort(int r[],int r1[],int n) {
int h=1;
while(h<n)
{
MergePass(r, r1, n, h);//排序好的数组我们放到暂存数组中了
h=2*h;
MergePass(r1,r ,n, h);//我们把暂存数组中的倒到我们原数组中和
h=2*h;
}
}