数据结构与算法之归并排序
生活随笔
收集整理的這篇文章主要介紹了
数据结构与算法之归并排序
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
數據結構與算法之歸并排序
目錄:
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排完。
總結
以上是生活随笔為你收集整理的数据结构与算法之归并排序的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 数据结构与算法之快速排序
- 下一篇: 数据结构与算法之基数排序