歸併排序代碼實現【遞歸實現+迭代實現】

1、歸併排序--遞歸實現

2、歸併排序--迭代實現



1、歸併排序--遞歸實現

package aa;

import java.util.Arrays;

public class MergeSort2 {

	//分解
	public static void sort(int[] arr,int low,int high){
		if(low<high){
			int mid=(low+high)/2;
			sort(arr,low,mid);//左邊排序+分解
			sort(arr,mid+1,high);//右邊排序+分解
			
			merge(arr,low,mid,high);//合併+排序
		}
	}
	
	//合併
	public static void merge(int[] arr,int low,int mid,int high)//合併
	{
		//獲取左邊的元素   +  獲取右邊的元素   大小的判斷
		
		int i=low;//左邊開始下標
		int j=mid+1;//右邊開始下標
		
		int k=0;//臨時數組下標
		int temp[]=new int[high-low+1];//臨時數組存放元素
		while(i<=mid && j<=high){
			if(arr[i]<arr[j]){
				temp[k++]=arr[i++];//左邊的元素小,放入
			}
			else{
				temp[k++]=arr[j++];//右邊的元素小,放入
			}
		}
		
		//剩餘元素判斷
		while(i<=mid){
			temp[k++]=arr[i++];//左邊元素
		}
		while(j<=high){
			temp[k++]=arr[j++];//右邊元素
		}
		System.out.println("此時temp:"+Arrays.toString(temp));
		
		//改變原來的arr數組
		//如何覆蓋元素的問題!!!!!!!!!!!!!!
		//將區間爲low,high的元素進行覆蓋  [      ] 
		//原因low~high區間的元素,在此處進行了排序
		k=0;
		while(low<=high){
			arr[low++]=temp[k++];
		}
		
//		  t = 0;
//        //將temp中的元素全部拷貝到原數組中
//        while(left <= right){
//            arr[left++] = temp[t++];
//        }
		
	}
	public static void main(String[] args) {
		int[] arr={5,7,1,9,2,6,3,4};
		System.out.println("111排序前:"+Arrays.toString(arr));
		
		sort(arr,0,arr.length-1);
		
		System.out.println("111排序後:"+Arrays.toString(arr));
	}

}


2、歸併排序--迭代實現

package sort;

import java.util.Arrays;

//迭代的方式進行  歸併排序
public class IterationMergeSort {

	//迭代
	/*
		//第一次  比較兩個元素   從 low 到high ,即兩個爲一組,進行比較     步長爲1
		//第二次  比較四個元素   從 low 到high ,即四個爲一組,進行比較     步長爲2
		//第三次  比較八個元素   從 low 到high ,即八個爲一組,進行比較     步長爲4
		//......
		//第n次  比較2*n個元素   從 low 到high ,即2*n個爲一組,進行比較     步長爲n
		
	 */
	public static void sort(int[] arr,int low,int high){  //sort(arr,0,arr.length-1);
		
		
		int left_low=0,left_high=0;//一組元素的左邊部分
		int right_low=0,right_high=0;//一組元素的右邊部分
		
		int temp[] = new int[high];
		
		
		for(int i=low;i<high;i=2*i){//一次迭代,步長增長
			
			//從 數組的   low  到 high 位置,依次進行比較,補償爲n,一組元素個數爲2*n進行比較
			
//			for(;right_high<high;left_low=right_high){//錯誤
//			for(left_low=0;right_high<high-i;left_low=right_high){
			
			for(left_low=0;left_low<high-i;left_low=right_high){//left_low=right_high  從下一組中,開始進行比較
				
				//此處,變量名字寫錯
//				left_high=low+i;//左邊結束
//				right_low=low+i;//右邊開始
//				right_high=right_low+i;//右邊結束
				
				left_high=left_low+i;//左邊結束
				right_low=left_low+i;//右邊開始
				right_high=right_low+i;//右邊結束
				
				if(right_high>high){
					right_high=high;//確保right_high小於等於high
				}
				
				//int temp[] =new int[right_high-left_low+1];//創建臨時數組存放排好序的元素
				
				
				int k=0;//臨時數組的下標
				
				//比較過程,類似於合併排序的  遞歸的比較
				while(left_low<left_high    &&    right_low <right_high){
					if(arr[left_low]<arr[right_low]){//左邊的 < 右邊的
						temp[k++]=arr[left_low++];
					}
					else{
						temp[k++]=arr[right_low++];
					}
				}
				
				//未比較完的,則進行補充即可
				while(left_low  <  left_high){
					temp[k++]=arr[left_low++];//補充左邊
				}
				// 上面循環結束的條件有兩個,如果是左邊的遊標尚未到達,那麼需要把
				// 數組接回去,可能會有疑問,那如果右邊的沒到達呢,其實模擬一下就可以
				// 知道,如果右邊沒到達,那麼說明右邊的數據比較大,這時也就不用移動位置了
//				while(right_low <right_high){
//				temp[k++]=arr[right_low++];//補充右邊
//				}
				
				System.out.println("temp::"+Arrays.toString(temp));

				
				//將排好序的元素,進行賦值到原來的數組中
				while(k>0){//將  low  ~ high區間的元素進行排序
					arr[--right_low]=temp[--k];
				}
			}
		}
		
	}
	
	public static void main(String[] args) {

		
//		int[] arr={5,7,1,9,2,6,3,4};
		int arr[] = { 5, 2, 6, 0, 3, 9, 1, 7, 4, 8 };
		System.out.println("迭代合併--排序前:"+Arrays.toString(arr));
		sort(arr,1,arr.length);
//		sort(arr,0,arr.length-1);
		System.out.println("迭代合併--排序後:"+Arrays.toString(arr));
		
	}

}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章