归并排序实现原理的个人理解
将数组不断等分成一个个小数组,再对每个小数组进行排序合并成一个新的有序数组。特点:稳定,当元素相同时不移动元素的位置,按照输入顺序来排,比较次数一般少于快排,移动次数一般多于快排
JavaScript递归实现:
function merge(left, right){
var result = [];
while(left.length > 0 && right.length>0){
if(left[0] < right[0]){
result.push(left.shift());
}else{
result.push(right.shift());
}
}
return result.concat(left).concat(right); //其中某个数组为空了,将剩下的接入
}
function sort(item){
if(item.length == 1)
return item;
var middle = Math.floor(item.length / 2),
left = item.slice(0, middle),
right = item.slice(middle);
return merge(sort(left), sort(right)); //递归将每个元素都分别成对排序了
}
var num = [1,15,74,65,23,6];
console.log(sort(num));
java递归实现:
public class MergeSort {
public static int[] MergeSort(int[] nums, int l, int h) { //i,h便于后面递归的时候分裂数组
if(l==h) { //传入数组的首尾两个下标
return new int[] {nums[l]}; //??
}
int mid = (l+h)/2;
int[] left = MergeSort(nums, l, mid); //分裂数组,对每个小数组进行排序
int[] right = MergeSort(nums, mid+1, h);
int[] newNum = new int[left.length + right.length];
int m = 0, i = 0, j = 0;
while(i!=left.length && j != right.length) {
newNum[m++] = left[i] < right[j] ? left[i++] : right[j++];
}
//将剩下的一个非空数组全放入新数组中
while( i < left.length) {
newNum[m++] = left[i++];
}
while(j < right.length) {
newNum[m++] = right[j++];
}
return newNum;
}
public static void main(String[] args) {
int [] nums = new int[]{1,65,75,23};
int [] newNums = MergeSort(nums, 0, nums.length-1);
for(int item : newNums) {
System.out.println(item);
}
}
}
java非递归实现
public class MergeSort {
public static int[] MergeSort(int[] nums) {
int step = 1;
int len = nums.length;
int [] temp = new int[len];
while(step<len) {
int i = 0;
int left,right,lTop,rTop; //设置左右数组边界
while(i<len) {
left = i;
lTop = i + step - 1;
right = lTop + 1;
if(right + step - 1 > len -1) {
rTop = len - 1;
}else {
rTop = right + step - 1;
}
//将每个小数组分别排序
int p = left; //左数组下标
int q = right; //右数组下标
int k = left; //临时存储数组的下标
while(p<=lTop && q <=rTop) { //排序插入临时数组
if(nums[p] <= nums[q]) {
temp[k++] = nums[p++];
}else {
temp[k++] = nums[q++];
}
}
//将多余的数组元素塞进去
while(p<=lTop) {
temp[k++] = nums[p++];
}
while(q<=rTop) {
temp[k++] = nums[q++];
}
for(int j = left; j <= rTop; j++) {
nums[j] = temp[j];
}
i+=2*step ; //进行下一批的左右数组排序
}
step = 2*step; //扩大一倍排序数组的大小,相当于将小数组合并了
}
return nums;
}
public static void main(String[] args) {
int [] nums = new int[]{1,6,4};
int [] newNums = MergeSort(nums);
for(int item : newNums) {
System.out.println(item);
}
}
}