package innersort;
public class MergeSort {
/**
* @param args
*/
public static void main(String[] args) {
int[] oldArr1 = { 65, 97, 76, 13, 27, 49, 49, 38, 89, 300, 105, 666,
10, 29, 122, 169,233,201 };
oldArr1 = mergeSort1(oldArr1);
print(oldArr1);
}
/**
* 先进行归并排序,然后将剩余的元素放在辅助数组的后面,所以辅助数组很重要。
*
* @param pArr
* @return
*/
static int[] mergeSort1(int[] pArr) {
int c = 2, len = pArr.length;
int[] tArr = new int[len];
while (c <= len) {
for (int i = 0; i < len; i += c) {
int high = i + c - 1;
if (high < len)
mergeChildSort(pArr, i, i + c - 1);// 左边进行归并
else
mergeChildSort(pArr, i, len - 1);// 右边进行归并
}
c *= 2;
}// while 以2为基数进行归并排序,然后以2*2为基数进行归并排序,以此类推
c /= 2;
if (c == len)
return pArr;
else if (!lt(pArr[c - 1], pArr[c])) { // //c是以2底的幂级数,这可能会造成len有部分数没有归并。如果下标c就比下标c-1小,这说明该数组已经有序了,因为c+1肯定比c大
int i = 0, j = c, base = 0;
while (i < c && j < len) { // 将下标为0~c-1的数为一个左子数组,而c~len-1为另一个右子数组。通过比较数组的值,将较小值放在新数组的对应下标base的位置上。
if (lt(pArr[i], pArr[j])) {
tArr[base] = pArr[i];
i++;
} else {
tArr[base] = pArr[j];
j++;
}
base++;
}
while (i < c) { // 可能左数组还有剩余项,将其放在新数组的后面
tArr[base] = pArr[i];
i++;
base++;
}
while (j < len) {// 可能右数组还有剩余项,将其放在新数组的后面
tArr[base] = pArr[j];
j++;
base++;
}
}
return tArr;
}
/**
* 这里要进行排序,也即从下标start开始,到下边end结束的数组元素进行排序。
*
* @param pArr
* @param start
* @param end
*/
static void mergeChildSort(int[] pArr, int start, int end) {
int tmp = 0, base = 0;
while (start < end) {
base = start;
for (int i = start + 1; i <= end; i++) {
if (lt(pArr[i], pArr[base]))
base = i;
}
if (base != start) {
tmp = pArr[base];
pArr[base] = pArr[start];
pArr[start] = tmp;
}
start++;
}
}
static boolean lt(int a, int b) {
return a - b <= 0 ? true : false;
}
static void print(int[] pArr) {
for (int var : pArr) {
System.out.print(var + " ");
}
}
}
归并排序
最新推荐文章于 2023-08-05 16:46:02 发布