日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

数据结构与算法之归并排序

發布時間:2024/2/28 编程问答 26 豆豆
生活随笔 收集整理的這篇文章主要介紹了 数据结构与算法之归并排序 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

數據結構與算法之歸并排序


目錄:

  • 歸并排序介紹
  • 歸并排序思想示意圖
  • 代碼實現

  • 1. 歸并排序介紹

    歸并排序(MERGE-SORT)是利用歸并的思想實現的排序方法,該算法采用經典的分治(divide-and-conquer)策略(分治法將問題分(divide)成一些小的問題然后遞歸求解,而治(conquer)的階段則將分的階段得到的各答案"修補"在一起,即分而治之)。

    歸并排序是建立在歸并操作上的一種有效的排序算法,該算法是采用分治法的一個非常典型的應用。將已有序的子序列合并,得到完全有序的序列。即先將每個子序列有序,再使子序列短間有序。它的時間復雜度是 O(nlogn),空間復雜度是 O(n),是穩定的排序算法


    2. 歸并排序思想示意圖

  • 歸并排序思想示意圖1-基本思想:

    說明:
    可以看到這種結構很像一棵完全二叉樹,本文的歸并排序我們采用遞歸去實現(也可采用迭代的方式去實現)。分階段可以理解為就是遞歸拆分子序列的過程。

  • 歸并排序思想示意圖2-合并相鄰有序子序列:
    再來看看治階段,我們需要將兩個已經有序的子序列合并成一個有序序列,比如上圖中的最后一次合并,要將[4,5,7,8]和[1,2,3,6]兩個已經有序的子序列,合并為最終序列[1,2,3,4,5,6,7,8],來看下實現步驟


  • 3. 代碼實現

    代碼實現一:

    import java.util.Arrays;public class MergeSort {public static void main(String[] args) {int[] arr= {5,3,1,2,6};mergeSort(arr);System.out.println(Arrays.toString(arr));}private static void mergeSort(int[] arr) {if (arr==null||arr.length<2)return;mergeSort(arr,0,arr.length-1);}private static void mergeSort(int[] arr,int l,int r) {if (l == r)return;int mid = (l+r)/2;mergeSort(arr,l,mid);mergeSort(arr,mid+1,r);merge(arr,l,mid,r);}private static void merge(int[] arr, int l, int mid, int r) {int[] help = new int[r-l+1];int i = 0;int p1 = l;int p2 = mid+1;while (p1<=mid&&p2<=r)help[i++] = arr[p1]<arr[p2]?arr[p1++]:arr[p2++];while (p1<=mid)help[i++] = arr[p1++];while (p2<=r)help[i++] = arr[p2++];for (i = 0; i < help.length; i++)arr[l+i] = help[i];} }

    代碼實現二:

    import java.util.Arrays;public class MergeSort {public static void main(String[] args) {int[] arr = {8,4,5,7,1,3,6,2};int temp[] = new int[arr.length];mergeSort(arr, 0, arr.length - 1, temp);System.out.println("歸并排序后=" + Arrays.toString(arr));}//分+合的方法public static void mergeSort(int[] arr, int left, int right, int[] temp) {if (left < right) {int mid = (left + right) / 2; //中間索引//向左遞歸進行分解mergeSort(arr, left, mid, temp);//向右遞歸進行分解mergeSort(arr, mid + 1, right, temp);//到合并merge(arr, left, mid, right, temp);}}//合并的方法/*** @param arr 帶排序的原始數組* @param left 左邊有序序列的初始索引* @param mid 中間索引* @param right 右邊索引* @param temp 中轉的數組*/public static void merge(int[] arr, int left, int mid, int right, int[] temp) {int i = left; //初始化i,左邊有序序列的初始索引int j = mid + 1; //右邊有序序列的初始化索引int t = 0; //指向temp數組的當前索引//1. 先把左右兩邊的數據按規則填充到temp數組//直到左右兩邊的有序序列,有一邊處理完畢為止while (i <= mid && j <= right) { //繼續if (arr[i] <= arr[j]) {//如果左邊的有序序列的當前元素,小于等于右邊有序序列的當前元素//即將左邊的當前元素,拷貝到temp數組//然后t++,i++temp[t] = arr[i];++t;++i;} else { //反之將右邊有序序列的當前元素填充到temp數組temp[t] = arr[j];++t;++j;}}//2. 把有剩余數據的一邊的數據依次填充到tempwhile (i <= mid) { //左邊的有序序列還有剩余的元素,就全部填充到temptemp[t] = arr[i];++t;++i;}while (j <= right) { //右邊的有序序列還有剩余的元素,就全部填充到temptemp[t] = arr[j];++t;++j;}//3. 將temp數據的元素拷貝到arr//注意:不是每次都拷貝所有t = 0;//第一次合并tempLeft = 0 ,right = 1 // tempLeft=2 ,right= 3 //tempLeft=0,right=3for (int tempLeft = left; tempLeft <= right; ++tempLeft) {arr[tempLeft] = temp[t];++t;}} }

    編譯結果

    800萬條數據大概3s排完。

    總結

    以上是生活随笔為你收集整理的数据结构与算法之归并排序的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。