算法笔记(第一部分)-- 排序之白话归并排序

归并排序是一种基于比较的排序算法,在多数的实现方法下它是稳定的。归并排序可是由计算机祖师级人物-冯 诺依曼提出的哦。

归并排序的过程:
1. 如果数据链表的长度为0或1,则返回
2. 将原始数据链表对半分成两个子链表
3. 对每个子链表递归的调用合并排序进行排序
4. 合并两个子链表使其成为一个排序完成的链表

归并排序的时间复杂度为[i]О(nlogn)[/i],空间复杂度为[i]О(n)[/i]。

归并排序的动画:
[img]http://upload.wikimedia.org/wikipedia/en/c/c5/Merge_sort_animation2.gif[/img]

归并排序代码-mergesort:

public int[] mergeSort(int[] data){
if(data.length<=1)
return data;
int middle = data.length/2;
int[] left = new int[middle];
int[] right = new int[data.length-middle];
for(int i=0; i<left.length; i++){
left[i] = data[i];
}
for(int i=0; i<right.length;i++){
right[i] = data[middle+i];
}
left = mergeSort(left);
right = mergeSort(right);
int[] result = merge(left, right);
return result;
}
public int[] merge(int[] left,int[] right){
int result[] = new int[left.length + right.length];
int index = 0;//index of result
int x = 0;//index of left
int y = 0;//index of right

//compare each element in two arrays, after comparing, index++.
while(x<left.length && y<right.length){
if(left[x]<right[y]){
result[index++] = left[x++];
}else{
result[index++] = right[y++];
}
}

//the length of two arrays might be different,
//so we have to copy the rest elements in two arrays
while(x<left.length)
result[index++] = left[x++];
while(y<right.length)
result[index++] = right[y++];
return result;
}


归并排序的示意图:
[img]http://www.iteye.com/upload/picture/pic/20935/1fd52b3d-cca1-390d-9c2d-2db11b3021b2.gif[/img]

由以上示意图可以看出mergesort的过程很简单,白话一点就是:拆分拆分拆分直至每个链表中仅有一个元素,合并合并合并至最终排好序的链表。merge是核心,经过递归调用归并排序后产生的left与right是已经排好序的两个子链表,依次比较left与right中的两数,将其放入适当的位置,然后删除子链表中已经放入result的那个数,最后将left与right中剩余的数依次放入result。问题:在实现的算法中,每次都要产生很多临时的list,这样效率是不是不高?

另曾经去一家小公司面试,工程师出了一道题:给定两个排好序的数组,如何将其合并是新的数组依然有序,似乎就是归并排序的应用,我的答案:


public int[] merge(int[] left,int[] right){
int result[] = new int[left.length + right.length];
int index = 0;//index of result
int x = 0;//index of left
int y = 0;//index of right

//compare each element in two arrays, after comparing, index++.
while(x<left.length && y<right.length){
if(left[x]<right[y]){
result[index++] = left[x++];
}else{
result[index++] = right[y++];
}
}

//the length of two arrays might be different,
//so we have to copy the rest elements in two arrays
while(x<left.length)
result[index++] = left[x++];
while(y<right.length)
result[index++] = right[y++];
return result;
}


代码的思想:将两个数组中的每一个数经过比较填入结果数组,由于可能两个数组的长度不等,最后还要将那个数组中剩余的数填入结果数组。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值