归并排序(java)

归并排序的基本思想:假设初始未排序序列有个n个记录, 可以看成是n个子序列,每个子序列的长度为1, 将他们两两归并, 得到ceiling(n/2)个长度为2或者1的有序子序列;再两两归并...直到得到一个长度为n的有序序列为止。

稳定性: 两两比较,不存在跳跃,归并排序是一种稳定的排序算法。

递归方法实现
public class Sort() {
  public static void mergeSort(int[] arr, int left, int right) {
    if(left < right){ //条件不成立时说明已经递归到长度为1的子序列
      int mid  = left + (right - left) / 2;
      mergeSort(arr, left, m);  //递归左子序列
      mergeSort(arr, m + 1, right); // 递归右子序列
      merge(arr, left, m, right) //对左右子序列归并排序
    }  
}

  public static void merge(int[] arr, int left, int mid, int right) {
    int tempArray = new int[arr.length]
    int i = left, j = mid + 1, k = left; // k = left很关键,最后将tempArray值赋到arr时可以对应
    while(i <= mid && j <= right) {
      if(arr[i] <= arr[j]) tempArray[k++] = arr[i++];
      else tempArray[k++] = arr[j++];
    }
    while(i > mid) tempArray[k++] = arr[i++];
    while(j > right) tempArray[k++] = arr[j++];
  }
  for(k = left; k <= right; k++) arr[k] = tempArray[k];
}

  public static void main(String[] args) {
    int[] arr = {50, 10, 90, 30, 70, 40, 80, 60, 20};
    Sort.mergeSort(arr, 0, arr.length - 1);
    for(int num: arr) {
      System.out.print(num + " ");
    }
  }

时间复杂度: 每次合并比较次数n次, 总共递归次数次,所以O(nlogn)



非递归方法实现
  public static void mergeSort(int[] arr, int length) {
    int step  = 1;  
    while(k < arr.length) {
      mergeIteration(arr, step, length);
      k *= 2;
    }
  }
  
  public static void mergeIteration(int[] arr, int step, int length) {
    int i = 0;
    while((length - i) >= 2 * step) { //条件成立:剩余未排序的个数大于两倍的子序列的长度
      merge(arr, i, i + step - 1, i + 2 * step - 1); //与递归方法中的merge相同
      i = i + 2 * step;
    }
    if(length > 2 * step && length < 4 * step) { //对倒数第二层,只剩两个子序列的情况进行排序
      merge(arr, 0, 2 * step - 1, len - 1);
    }
  }

  public static void main(String[] args) {
    int[] arr = {50, 10, 90, 30, 70, 40, 80, 60, 20};
    Sort.mergeSort(arr, 0, arr.length - 1);
    for(int num: arr) {
      System.out.print(num + " ");
    }
  }

你可能感兴趣的:(归并排序(java))