三路归并排序

三路归并算法的关键在于分割点的下标计算
package fenzhi;

public class MergeSortTest {  
	  
    public static void main(String[] args) {  
        int[] data = new int[] { 5, 3, 6, 2, 16, 9, 4,  5, 3, 6, 2, 16, 9, 4, 7,10,11,15, 8,12,13,1,14,7,10,11,15, 8,12,13,1,14,  5, 3, 6, 2, 16, 9, 4, 7,10,11,15, 8,12,13,1,14};  
        print(data);  
        mergeSort(data);  
        System.out.println("排序后的数组:");  
        print(data);  
    }  
  
    public static void mergeSort(int[] data) {  
        sort(data,0,data.length -1);  
    }  
  
    public static void sort(int[] data, int left, int right) {  
        if (left >= right)  
            return;  
        // 找出中间索引  
        int center_first = left+((right-left)/3); 
        int center_next=right-(right-left)/3;
        // 对左边1/3数组进行递归  
        sort(data, left, center_first);
        // 对中间1/3数组进行递归  
        sort(data, center_first + 1, center_next);
        // 对右侧1/3数组进行递归  
        sort(data,center_next+ 1, right);
        // 合并  
        merge(data, left, center_first,center_next, right);
        print(data);  
    }  
  
   
    public static void merge(int[] data, int left, int center_first,int center_next, int right) {  
        // 临时数组  
        int[] tmpArrList = new int[data.length];  
        // 三段数组的三个起点
        int first=left;
        int second = center_first+1; 
        int third=center_next+1;
        
        //临时数组的起点  
        int num=left;
      
        int tmp=left;
      
        while (first <= center_first && second<=center_next&&third <= right) {  
            // 从三个数组中取出最小的放入临时数组  
            if (data[first] <= data[second]&&data[first]<=data[third]) {  
                tmpArrList[num] = data[first];
                first++;
                num++;
            } 
            else if(data[second] <= data[first]&&data[second]<=data[third]){
            	 tmpArrList[num] = data[second];
                 second++;
                 num++;
            }
            else {  
            	tmpArrList[num] = data[third];
                third++;
                num++;
            }  
        }  
        // 当有一个数组率先全部排进临时数组后,继续排剩下的两个数组
        while (first <= center_first&&second<=center_next) {  
        	 if (data[first] <= data[second]) {  
                 tmpArrList[num] = data[first];
                 first++;
                 num++;
             } 
        	 else{
        		 tmpArrList[num] = data[second];
                 second++;
                 num++;
        	 }
        }  
        while (second <= center_next&&third<=right) {  
       	 if (data[second] <= data[third]) {  
                tmpArrList[num] = data[second];
                second++;
                num++;
            } 
       	 else{
       		 	tmpArrList[num] = data[third];
       		 	third++;
       		 	num++;
       	 }
       }  
        while (first <= center_first&&third<=right) {  
          	 if (data[first] <= data[third]) {  
                   tmpArrList[num] = data[first];
                   first++;
                   num++;
               } 
          	 else{
          		 tmpArrList[num] = data[third];
                   third++;
                   num++;
          	 }
          }  
        //当两个数组全部排进临时数组后,只剩下一个数组
        while (first <= center_first){
        	tmpArrList[num] = data[first];
        	 first++;
             num++;
        }
        while (second <= center_next){
        	tmpArrList[num] = data[second];
        second++;
        num++;
        }
        while(third<=right){
        	tmpArrList[num] = data[third];
            third++;
            num++;
        }
        // 将临时数组中的内容拷贝回原数组中  
        // (原left-right范围的内容被复制回原数组)  
        while (tmp <=right) {  
            data[tmp] = tmpArrList[tmp];
            tmp++;
        }  
    }  
  
    public static void print(int[] data) {  
        for (int i = 0; i < data.length; i++) {  
            System.out.print(data[i] + "  ");  
        }  
        System.out.println();
    }  
}  

猜你喜欢

转载自blog.csdn.net/kangyucheng/article/details/40015803
今日推荐