归并排序

来源:互联网 发布:cab a4 编辑软件 编辑:程序博客网 时间:2024/05/01 03:46
归并操作(merge),也叫归并算法,指的是将两个顺序序列合并成一个顺序序列的方法。
如 设有数列{6,202,100,301,38,8,1}
初始状态:6,202,100,301,38,8,1
第一次归并后:{6,202},{100,301},{8,38},{1},比较次数:3;
第二次归并后:{6,100,202,301},{1,8,38},比较次数:4;
第三次归并后:{1,6,8,38,100,202,301},比较次数:4;
总的比较次数(逆序数)为:3+4+4=11;
归并操作的工作原理如下:
第一步:申请空间,使其大小为两个已经排序序列之和,该空间用来存放合并后的序列
第二步:设定两个指针,最初位置分别为两个已经排序序列的起始位置
第三步:比较两个指针所指向的元素,选择相对小的元素放入到合并空间,并移动指针到下一位置
重复步骤3直到某一指针超出序列尾
将另一序列剩下的所有元素直接复制到合并序列尾
package stone.test.sort;import java.util.Arrays;public class MergeSort {/** * @param args */public static void main(String[] args) {// TODO Auto-generated method stubint[] data = {77, 99, 44, 55, 22, 88, 11, 0, 66};new MergeSort().mergeSort(data,data.length);}public void mergeSort(int[] data, int n){int len = 1,k=0;int[] data2 = new int[n];while(len<n){if(k==0){mSort(data,data2,n,len);System.out.println(Arrays.toString(data2));}else{mSort(data2,data,n,len);System.out.println(Arrays.toString(data));}len *= 2;k = 1-k;}if(k == 1){ //结果在data2上for(k=0;k<n;k++){data[k] = data2[k];}}System.out.println(Arrays.toString(data));}private void mSort(int[] data, int[] data2, int n, int len){//两两归并,将结果放在data2上int start_p, end_p;start_p = 0;while(start_p + len < n){ // 每次取相邻的两个有序段进行归并end_p = start_p+2*len -1;if(end_p >= n) end_p = n-1;merge(data,data2,start_p,start_p+len-1,end_p);start_p = end_p + 1;}if(start_p < n){ //直接将剩下的一个有序段中的元素复制到data2中for(;start_p<n;start_p++){data[start_p] = data[start_p];}}}/** * 合并两个有序序列 * @param data * @param begin * @param mid * @param end */private void merge(int[] data, int[] temp, int begin, int mid, int end){/*将data[begin..mid]和data[mid+1..end]归并为有序的temp[]*/int left = begin;int end_1 = mid;int right = mid+1;int end_2 = end;int i = begin;while(left<= end_1 && right <= end_2){//从两个数组中取出最小的放入中间数组if(data[left] < data[right]){temp[i++] = data[left++];}else{temp[i++] = data[right++];}}//剩余部分依次放入中间数组while(left <= end_1){temp[i++] = data[left++];}while(right <= end_2){temp[i++] = data[right++];}//将中间数组中的内容复制回原数组i = begin;while(i<=end){data[i] = temp[i++];}}}

递归方法:

public void mergeSort(int[] data, int begin, int end){if(begin<end){int mid = (begin+end)/2;//对左边数组进行递归mergeSort(data,begin,mid);//对右边数组进行递归mergeSort(data,mid+1,end);merge(data,begin,mid,end);}}/** * 合并两个有序序列 * @param data * @param begin * @param mid * @param end */private void merge(int[] data, int begin, int mid, int end){int[] temp = new int[data.length];int left = begin;int end_1 = mid;int right = mid+1;int end_2 = end;int i = begin;while(left<= end_1 && right <= end_2){//从两个数组中取出最小的放入中间数组if(data[left] < data[right]){temp[i++] = data[left++];}else{temp[i++] = data[right++];}}//剩余部分依次放入中间数组while(left <= end_1){temp[i++] = data[left++];}while(right <= end_2){temp[i++] = data[right++];}//将中间数组中的内容复制回原数组i = begin;while(i<=end){data[i] = temp[i++];}System.out.println(Arrays.toString(data));}



原创粉丝点击