归并算法(非递归版)
用二叉堆排序的概念,自底向上,分层排序。缺点是不直观,理解有困难,算法较复杂。
算法
def merge_sort_norecurse (array) :
j = 1 ;
while j < array.length :
i = 1 ;
// 最右侧节点的左子序列,其最后一个元素的下标应小于数组长度
while i + j - 1 < n :
合并两个有序列,下标分为,i,i+1 ,...i+j-1 和i+j,i+j+1 ,...min(i+2j -1 ,n)
i += 2j ; //横向以纵向步长的2 倍进行跳跃
end while
j *= 2 ; //纵向以2 的幂次方步长跳跃
合并算法
def merge_array(data, work, start, mid, end ) :
midStart = mid + 1 ;
int memoryStart = start;
index = 0 ;
while start <= mid 且 midStart <= end :
work[index ++] = data[start] <= data[midStart] ?
data[start++]:data[midStart++];
end while
while start <= mid :
work[index ++] = data[start++];
end while
while midStart <= end :
work[index ++] = data[midStart++];
end while
index --;
while index >= 0 :
data[memoryStart + index ] = work[index --];
end while
算法测试
import java.util.Arrays;
public class Test {
public static void main (String[] args) {
int [] a = { 10 , 9 , 8 , 7 , 6 , 5 , 4 , 3 , 2 , 1 , 0 };
merge_sort(a, new int [a.length]);
System.out.println(Arrays.toString(a));
}
private static void merge_sort (int [] data, int work[]) {
int n = data.length;
int j = 1 ;
int i = 0 ;
while (j < n) {
i = 0 ;
while (i + j < n) {
merge_array(data, work, i, i + j - 1 , Math.min(i + 2 * j - 1 , n - 1 ));
i += 2 * j;
}
j *= 2 ;
}
}
/**
* 将数组data中待合并处理的数据,按序整理好放入work中, 在将work中数据放回data相应位置
*
* @param data
* 待进行合并处理的数组
* @param work
* 用于存储合并处理数据的数组
* @param low
* data数组中,需要合并处理的左端起始下标
* @param mid
* data数组中,需要合并处理的左端终点下标
* @param high
* data数组中,需要合并处理的右端终点下标
*/
private static void merge_array (int [] data, int [] work, int low, int mid, int high) {
int index = 0 ;
int lowRight = mid + 1 ;
int i = 0 ;
int memoryStart = low;
while (low <= mid && lowRight <= high) {
if (data[low] <= data[lowRight]) {
work[index++] = data[low++];
} else {
work[index++] = data[lowRight++];
}
}
while (low <= mid) {
work[index++] = data[low++];
}
while (lowRight <= high) {
work[index++] = data[lowRight++];
}
index--;
while (index >= 0 ) {
data[memoryStart + index] = work[index--];
}
}
}