归并排序
归并排序简介
并排序(MERGE-SORT)是建立在归并操作上的一种有效的排序算法,该算法是采用分治法(Divide and Conquer)的一个非常典型的应用。将已有序的子序列合并,得到完全有序的序列;即先使每个子序列有序,再使子序列段间有序。
思路分析
- 将要排序的数据对半分 意为左边的数据和右边的数据
- 重复第一步操作直到只有一个数
- 将左边的数据和右边的数据进行排序
代码再现
public class MergeSort {
public static void sort(int[] data){
assert data!=null ? true:false;
int len = data.length;
mergeSort(data,0,len-1);
}
public static void mergeSort(int[] data,int begin,int end){
if(begin < end) {//起始点 小于 结束点
int mid = ( end + begin )/2;
mergeSort(data, begin, mid);
mergeSort(data, mid+1, end);
merge(data, begin, mid, end);
}
}
/**
* 索引
* ==========
* 0 1 2 3
* ==========
3 5 2 4 begin=0,rightBegin=2
2 3 5 4 begin=1,rightBegin=3
2 3 5 4 begin=2,rightBegin=3
*/
private static void merge(int[] data,int begin,int mid,int end) {
int rightBegin = mid+1;//右边起始节点
int leftBegin = begin;
while(leftBegin <= rightBegin-1 && rightBegin <= end) {
//如果左边的开始节点比右边的开始节点大
if( data[leftBegin] > data[rightBegin] ) {
//将左边的开始节点到结束节点的数据集体右移一位
int temp = data[rightBegin];
for(int i= rightBegin; i > leftBegin ;i--) {
data[i] = data[i-1];
}
data[leftBegin]=temp;
//右边节点向后移动一位,前面节点的终止节点向后移动一位
rightBegin++;
}
//每次循环,前面的节点都要向后移动
leftBegin++;
}
System.out.println("归并:begin="+begin+",mid="+mid+",end="+end+",结果:"+Arrays.toString(data));
}
/**
*
* @param args
*/
public static void main(String[] args) {
int[] data = {9,1,5,3,7,4,2};
System.out.println("before:"+Arrays.toString(data));
sort(data);
System.out.println("after:"+Arrays.toString(data));
}
}
优化merge方法
/**
* merge地方优化为插入排序
*/
private static void merge2(int[] data,int begin,int mid,int end) {
int leftLast = mid;
for(int i=mid+1; i <= end ;i++) {//循环右边的数据
int temp = data[i];
int j = leftLast;
for(;j >= begin && temp < data[j];j--) {//将右边的数据与左边的最后一个数据作比较
data[j+1] = data[j];
}
if(j < leftLast) {
leftLast++;
data[j+1] = temp;
}
}
System.out.println("归并:begin="+begin+",mid="+mid+",end="+end+",结果:"+Arrays.toString(data));
}
执行结果
before:[9, 1, 5, 3, 7, 4, 2]
归并:begin=0,mid=0,end=1,结果:[1, 9, 5, 3, 7, 4, 2]
归并:begin=2,mid=2,end=3,结果:[1, 9, 3, 5, 7, 4, 2]
归并:begin=0,mid=1,end=3,结果:[1, 3, 5, 9, 7, 4, 2]
归并:begin=4,mid=4,end=5,结果:[1, 3, 5, 9, 4, 7, 2]
归并:begin=4,mid=5,end=6,结果:[1, 3, 5, 9, 2, 4, 7]
归并:begin=0,mid=3,end=6,结果:[1, 2, 3, 4, 5, 7, 9]
after:[1, 2, 3, 4, 5, 7, 9]
总结
归并排序是一个稳定高效的排序算法。算法时间复杂度为nlogn