归并排序小结
#include<iostream>
using namespace std;
//打印函数
void printArray(int A[],int n)
{
for (int i = 0; i < n;++i)
cout << A[i] << endl;
}
void MERGE(int A[],int p,int q,int r)
{
int n1 = q - p + 1;
int n2 = r-q;
int L[n1+1];
int R[n2+1];
for (int i = 0; i < n1;i++)
{
L[i] = A[p + i ];
}
//printArray(L, n1);
//cout << endl;
for (int j = 0; j < n2;j++)
{
R[j] = A[q+j+1];
}
//printArray(R, n2);
//cout << endl;
L[n1] = 1000;
R[n2] = 1000;
int i=0,j=0;
//我第一步写成k=0,错了。
//printArray(A, 4);
//cout << endl;
for (int k = first; k <= end;k++)
{
//cout << i << " " << j << endl;
if(L[i]<=R[j])
{
A[k] = L[i];
i++;
}
else
{
A[k] = R[j];
j++;
}
}
}
void MERGESORT(int A[],int p,int r)
{
if(p<r)
{
int q = (p + r) / 2;
MERGESORT(A, p, q);
MERGESORT(A, q+1, r);
MERGE(A, p, q, r);
}
}
int main()
{
int A[4]={6,2,1,0};
MERGESORT(A, 0, 3);
printArray(A,4);
}
结果:
1、合并函数MERGE
合并左边和右边有序的数组,使最后的合并的数组有序。就像{3,4,1,2}
左边和右边各有序,要使之最后变为{1,2,3,4}.
先将数组分为两部分,一个R,一个L。
R和L为有序。
之后再从R和L中选出最小的放在A数组中。
就像有两堆扑克牌,正面朝上并且已经拍好了顺序,从 1 到 10 到 K 。
然后从两堆扑克牌的最上方拿出最小的那一张背面朝上放在第三堆,依次类推,
知道有一堆被拿完了,另外一堆就直接全部反过来放到第三堆里面。
那为了知道最后是否那一堆牌全部拿完了,我们设置了一个哨兵牌,就是无穷
大,INT_MAX。也可以设置成比需要排序的数字都大的数,比如1000,100000.
这样,当拿到无穷大的时候,这堆牌就拿完了,只要把另一堆的全部放进去就可
以了。
2、MERGESORT函数
设最上面那张牌是第 p 张,最后一张就是第 r 张。中间那张就是第 q =( p + r) / 2
张.
只有第 p 张等于第 r 张的时候,那堆牌才全部拿完。
就这样迭代,分成最小单位(就是只有一个数的时候),最后用MERGE函数合并即可。