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));
}
}