归并排序算法介绍
归并排序是一个分治算法(Divide and Conquer)的一个典型实例,把一个数组分为两个大小相近(最多差一个)的子数组,分别把子数组都排好序之后通过归并(Merge)手法合成一个大的排好序的数组,归并的过程依然用扑克来解释,想象一下桌子上有两堆排好序(从小到大)的牌,每一次从两堆里面各抽取一张,比较一下两张的大小,如果两张一样大,都取出放到目标数组,否则取出较小的放到目标数组,另外一个放回原堆里面。归并排序需要额外的空间来存储临时数据,不过它的最坏运行时间都是O(nlogn)。
归并排序算法Java实现
如《插入排序(Insertsort)之Java实现》一样,先实现一个数组工具类。代码如下:
- publicclassArrayUtils{
- publicstaticvoidprintArray(int[]array){
- System.out.print("{");
- for(inti=0;i<array.length;i++){
- System.out.print(array[i]);
- if(i<array.length-1){
- System.out.print(",");
- }
- }
- System.out.println("}");
- }
- }
归并排序为分治法,分体现在把一个数组分为基本等长的两个子数组,重复这个过程,直到两个子数组都只有一个元素,归并的过程是算法的核心,前面已经提到过。归并排序的Java实现以及测试代码如下:
- publicclassMergeSort{
- publicstaticvoidmain(String[]args){
- int[]array={9,8,7,6,5,4,3,2,1,0,-1,-2,-3};
- System.out.println("Beforesort:");
- ArrayUtils.printArray(array);
- mergeSort(array);
- System.out.println("Aftersort:");
- ArrayUtils.printArray(array);
- }
- publicstaticvoidmergeSort(int[]array){
- sortArray(array,0,array.length-1);
- }
- privatestaticvoidsortArray(int[]array,intstart,intend){
- //单个元素不需要排序,直接返回
- if(start==end){
- return;
- }
- intsortSize=end-start+1;
- intseperate;
- if(sortSize%2==0){
- seperate=start+sortSize/2-1;
- }else{
- seperate=start+sortSize/2;
- }
- sortArray(array,start,seperate);
- sortArray(array,seperate+1,end);
- mergeArray(array,start,seperate,end);
- }
- privatestaticvoidmergeArray(int[]array,intstart,intseperate,intend){
- inttotalSize=end-start+1;
- intsize1=seperate-start+1;
- intsize2=end-seperate;
- int[]array1=newint[size1];
- int[]array2=newint[size2];
- for(inti=0;i<size1;i++){
- array1[i]=array[start+i];
- }
- for(inti=0;i<size2;i++){
- array2[i]=array[seperate+1+i];
- }
- intmergeCount=0;
- intindex1=0;
- intindex2=0;
- while(mergeCount<totalSize){
- //先检查有没有其中的一个数组已经处理完
- if(index1==size1){
- for(inti=index2;i<size2;i++){
- array[start+mergeCount]=array2[i];
- mergeCount++;
- index2++;
- }
- }elseif(index2==size2){
- for(inti=index1;i<size1;i++){
- array[start+mergeCount]=array1[i];
- mergeCount++;
- index1++;
- }
- }else{
- intvalue1=array1[index1];
- intvalue2=array2[index2];
- if(value1==value2){
- array[start+mergeCount]=value1;
- array[start+mergeCount+1]=value1;
- mergeCount+=2;
- index1++;
- index2++;
- }elseif(value1<value2){
- array[start+mergeCount]=value1;
- mergeCount++;
- index1++;
- }elseif(value1>value2){
- array[start+mergeCount]=value2;
- mergeCount++;
- index2++;
- }
- }
- }
- }
- }
归并排序算法介绍
归并排序是一个分治算法(Divide and Conquer)的一个典型实例,把一个数组分为两个大小相近(最多差一个)的子数组,分别把子数组都排好序之后通过归并(Merge)手法合成一个大的排好序的数组,归并的过程依然用扑克来解释,想象一下桌子上有两堆排好序(从小到大)的牌,每一次从两堆里面各抽取一张,比较一下两张的大小,如果两张一样大,都取出放到目标数组,否则取出较小的放到目标数组,另外一个放回原堆里面。归并排序需要额外的空间来存储临时数据,不过它的最坏运行时间都是O(nlogn)。
归并排序算法Java实现
如《插入排序(Insertsort)之Java实现》一样,先实现一个数组工具类。代码如下:
- publicclassArrayUtils{
- publicstaticvoidprintArray(int[]array){
- System.out.print("{");
- for(inti=0;i<array.length;i++){
- System.out.print(array[i]);
- if(i<array.length-1){
- System.out.print(",");
- }
- }
- System.out.println("}");
- }
- }
归并排序为分治法,分体现在把一个数组分为基本等长的两个子数组,重复这个过程,直到两个子数组都只有一个元素,归并的过程是算法的核心,前面已经提到过。归并排序的Java实现以及测试代码如下:
- publicclassMergeSort{
- publicstaticvoidmain(String[]args){
- int[]array={9,8,7,6,5,4,3,2,1,0,-1,-2,-3};
- System.out.println("Beforesort:");
- ArrayUtils.printArray(array);
- mergeSort(array);
- System.out.println("Aftersort:");
- ArrayUtils.printArray(array);
- }
- publicstaticvoidmergeSort(int[]array){
- sortArray(array,0,array.length-1);
- }
- privatestaticvoidsortArray(int[]array,intstart,intend){
- //单个元素不需要排序,直接返回
- if(start==end){
- return;
- }
- intsortSize=end-start+1;
- intseperate;
- if(sortSize%2==0){
- seperate=start+sortSize/2-1;
- }else{
- seperate=start+sortSize/2;
- }
- sortArray(array,start,seperate);
- sortArray(array,seperate+1,end);
- mergeArray(array,start,seperate,end);
- }
- privatestaticvoidmergeArray(int[]array,intstart,intseperate,intend){
- inttotalSize=end-start+1;
- intsize1=seperate-start+1;
- intsize2=end-seperate;
- int[]array1=newint[size1];
- int[]array2=newint[size2];
- for(inti=0;i<size1;i++){
- array1[i]=array[start+i];
- }
- for(inti=0;i<size2;i++){
- array2[i]=array[seperate+1+i];
- }
- intmergeCount=0;
- intindex1=0;
- intindex2=0;
- while(mergeCount<totalSize){
- //先检查有没有其中的一个数组已经处理完
- if(index1==size1){
- for(inti=index2;i<size2;i++){
- array[start+mergeCount]=array2[i];
- mergeCount++;
- index2++;
- }
- }elseif(index2==size2){
- for(inti=index1;i<size1;i++){
- array[start+mergeCount]=array1[i];
- mergeCount++;
- index1++;
- }
- }else{
- intvalue1=array1[index1];
- intvalue2=array2[index2];
- if(value1==value2){
- array[start+mergeCount]=value1;
- array[start+mergeCount+1]=value1;
- mergeCount+=2;
- index1++;
- index2++;
- }elseif(value1<value2){
- array[start+mergeCount]=value1;
- mergeCount++;
- index1++;
- }elseif(value1>value2){
- array[start+mergeCount]=value2;
- mergeCount++;
- index2++;
- }
- }
- }
- }
- }