前两天看到11年的一道阿里实习生笔试题,要求写一个Merge Sort,如下:
分析Merge Sort的原理以及算法复杂度,并用最擅长的编程语言实现Merge Sort。
当时自己第一反应是递归写。
打开Eclipse写完,感觉效率比较低,然后又试着写了个非递归的。写完一看每次调用归并函数,就要new 一个数组,而且为了防止数组越界,还得申请和原始数组一样大的数组空间,感觉空间很浪费,又想着如何减少这空间的消耗,于是就写出了这一版本的非递归归并排序
class MergeSort {
private int[] sr;
private int[] res;
public MergeSort(int[] sr) {
this.sr = sr;
this.res = new int[sr.length];
}
public void print() {
for (int i : res)
System.out.printf("%3d", i);
System.out.println();
}
public void sort() {
int sub = 1;
int cnt = 0;
while(sub < sr.length) {
mergePass(sub, cnt++);
sub *= 2;
}
if((cnt & 1) == 0) {
res = sr;
}
}
private void mergePass(int sub, int cnt) {
int i = 0;
while(i + sub <= sr.length) {
if(i + 2 * sub < sr.length) {
if((cnt & 1) == 0) {
merge(sr, res, i, i + sub, i + 2 * sub);
} else {
merge(res, sr, i, i + sub, i + 2 * sub);
}
} else {
if((cnt & 1) == 0) {
merge(sr, res, i, i + sub, sr.length);
} else {
merge(res, sr, i, i + sub, sr.length);
}
}
i += 2 * sub;
}
}
private void merge(int[] ary1, int[] ary2, int s, int m, int e) {
int i = s, j = m, k = s;
while(i < m && j < e) {
if(ary1[i] < ary1[j]) {
ary2[k++] = ary1[i++];
} else {
ary2[k++] = ary1[j++];
}
}
while(i < m) {
ary2[k++] = ary1[i++];
}
while(j < e) {
ary2[k++] = ary1[j++];
}
}
}