排序方法總結——Java語言描述

排序總結——Java語言描述

各種排序方法Java源代碼鏈接:各種排序方法Java源代碼鏈接

一 排序概述

1.1 排序的定義

排序是計算機內經常進行的一種操作,其目的是將一組“無序”的記錄序列調整爲“有序”的記錄序列。

1.2 排序的分類

排序分爲內部排序外部排序

內部排序:若整個排序過程不需要訪問外存便能完成(如軟盤、硬盤),則稱此類排序問題爲內部排序

外部排序:若參加排序的記錄數量很大,整個序列的排序過程**不可能在內存中
完成**,則稱此類排序問題爲外部排序


二 內部排序

2.1 內部排序概述

內部排序的過程是一個逐步擴大記錄的有序序列長度的過程。基於不同的“擴大” 有序序列長度的方法,內部排序方法大致可分下列幾種類型:
1**插入類**:將無序子序列中的一個或幾個記錄插入到有序序列中,從而增加記錄的有序子序列的長度。
1)直接插入排序(基於順序查找)
2) 折半插入排序(基於折半查找)
3) 希爾插入排序(基於逐趟縮小增量)

2 交換類:通過“交換”無序序列中的記錄從而得到其中關鍵字最小或最大的記錄,並將它加入到有序子序列中,以此方法增加記錄的有序子序列的長度

1) 冒泡排序

2) 快速排序

3 選擇類:從記錄的無序子序列中“選擇”關鍵字最小或最大的記錄,並將它加入到有序子序列中,以此方法增加記錄的有序子序列的長度。

1) 簡單選擇排序

2) 樹形選擇排序

3) 堆排序
4**歸併類**:通過“歸併”兩個或兩個以上的記錄有序子序列,逐步增加記錄有序序列的長度。

1) 歸併排序
5 其他類


2.2 各種排序方法詳解


插入類排序

2.2.1 直接插入排序法

a) 思想:利用 “順序查找”實現“在R[1..i-1]中查找R[i]的插入位置”

b) Java語言描述的關鍵代碼

package insertCategorySort;

import java.util.ArrayList;
import java.util.Scanner;

/**
* @Description 直接插入排序(基於順序查找)
* @author zhiman in 2017年10月7日 下午5:26:45 [email protected]
* @version V1.0
* 
*/
public class SimpleInsertionSort {


    public static void main(String[] args) {
        ArrayList<Integer> arrs = new ArrayList<Integer>();
        Scanner scanner = new Scanner(System.in);
        System.out.println("請輸入待排序數的個數:");
        int num = scanner.nextInt();
        System.out.println("請輸入待排數據:");
        for(int i = 0; i < num; i++){
            int temp = scanner.nextInt();
            arrs.add(temp);
        }
        scanner.close();
        Integer[] arr = new Integer[num];
        arrs.toArray(arr);
        //泛型方法調用
        System.out.println("排序完成後的數據:");
        SimpleInsertionSort.<Integer>insertionSort(arr);
        for(Integer in:arr) {
            System.out.println(in);
        }
    }
    /** 
    * TODO(方法功能描述) 直接插入排序核心代碼.
    * @author zhiman in 2017年10月7日 下午5:28:56 
    */
    public static <AnyType extends Comparable<? super AnyType>> 
        void insertionSort(AnyType[] data) {
        //暫存帶排序的元素
        int i;
        for(int pointer = 1; pointer < data.length; pointer++) {
            AnyType temp = data[pointer];
            for (i = pointer; i > 0 && temp.compareTo(data[i - 1]) < 0; i--) {
                //if (temp.compareTo(data[i-1]) < 0) 
                    data[i] = data[i - 1];
            }
            data[i] = temp;
        }
    }
}

c) 算法分析

直接插入排序法穩定的排序排序算法,時間複雜度爲O(n2)


2.2.2 折半插入排序法

a) 思想:利用 “折半查找”實現“在R[1..i-1]中查找R[i]的插入位置”

b) Java語言描述的關鍵代碼

package insertCategorySort;

import java.util.ArrayList;
import java.util.Scanner;

/**
* @Description TODO 折半插入排序法
* @author zhiman in 2017年10月7日 下午9:49:48 mail:[email protected]
* @version V1.0
* 
*/
public class BinaryInsertionSort {
    public static void main(String[] args) {
        ArrayList<Integer> arrs = new ArrayList<Integer>();
        Scanner scanner = new Scanner(System.in);
        System.out.println("折半插入排序——請輸入待排序數的個數:");
        int num = scanner.nextInt();
        System.out.println("折半插入排序——請輸入待排數據:");
        for(int i = 0; i < num; i++){
            int temp = scanner.nextInt();
            arrs.add(temp);
        }
        scanner.close();
        Integer[] arr = new Integer[num];
        arrs.toArray(arr);
        //泛型方法調用
        System.out.println("折半插入排序——排序完成後的數據:");
        new BinaryInsertionSort().<Integer>binaryInsert(arr);
        for(Integer in:arr) {
            System.out.println(in);
        }
    }   
    public <AnyType extends Comparable<? super AnyType>> 
        void binaryInsert(AnyType[] data) {
        int low,high,mid;
        for (int pointer = 1; pointer < data.length; pointer++) {
            AnyType temp = data[pointer];
            low = 0;
            high = pointer - 1;
            //查找元素插入位置
            while (low <= high) {
                mid = (low + high) / 2;
                if (temp.compareTo(data[mid]) < 0) {
                    high = mid - 1;
                } else {
                    low = mid + 1;
                }
            }
            //移動元素
            for (int j = pointer; j > high + 1; j--) {
                data[j] = data[j - 1];
            }
            //將待排元素放到合適位置,即high+1的位置
            data[high + 1] = temp;
        }
    }
}

c) 算法分析

折半插入排序法穩定的排序排序算法,時間複雜度爲O(n2)


2.2.3 希爾排序法

a) 算法思想:先將整個待排記錄序列分割成若干子序列分別進行直接插入排序,待整個序列中的記錄基本有序時,再對全體記錄進行一次直接插入排序。

b)算法描述

1、選擇一個步長序列t1,t2,tkti>ti+1tk=1

2、 按步長序列個數k,對序列進行k趟排序;

3、每趟排序,根據對應的步長ti ,將待排序列分割成若干長度爲m的子序列,分別對各子表進行直接插入排序。僅步長因子爲1時,整個序列作爲一個表來處理,表長度即爲整個序列的長度。

c)關鍵代碼

package insertCategorySort;

import java.util.ArrayList;
import java.util.Scanner;

public class ShellInsertionSort {
    public static void main(String[] args) {
        //ArrayList<Integer> arrs = new ArrayList<Integer>();
        Scanner scanner = new Scanner(System.in);
        System.out.println("希爾插入排序——請輸入待排序數的個數:");
        int num = scanner.nextInt();
        System.out.println("希爾插入排序——請輸入待排數據:");
        Integer[] arr = new Integer[num];
        for(int i = 0; i < num; i++){
            int temp = scanner.nextInt();
            arr[i] = temp;
        }
        scanner.close();

        //arrs.toArray(arr);
        //泛型方法調用
        System.out.println("希爾插入排序——排序完成後的數據:");
        new ShellInsertionSort().<Integer>shellInsert(arr);
        for(Integer in:arr) {
            System.out.println(in);
        }
    }
    /** 
    * TODO(方法功能描述) 希爾排序關鍵代碼
    * @param data 待排數據
    * @author zhiman in 2017年10月8日 上午11:15:54 
    */
    public <AnyType extends Comparable<? super AnyType>> 
        void shellInsert( AnyType[] data ) {
        //初始增量選擇data.length/2,後面增量依次選擇上次增量的0.5倍
        //這種增量叫做希爾增量
        for ( int gap = data.length/2; gap > 0; gap /= 2 ) {
            for ( int i = gap; i < data.length; i++ ) {
                AnyType temp = data[i];
                int j;
                for ( j = i;j >= gap/*&& temp.compareTo( data[ j - gap ] ) < 0*/; j -= gap ) {
                    if ( temp.compareTo( data[ j - gap ] ) < 0 ) {
                        data[ j ] = data[ j - gap ];
                    } else 
                        break;
                }
                data[ j ] = temp;
            }
        }
    }
}

d) 算法分析

1.希爾排序方法是一個不穩定的排序方法

2.關鍵字的比較次數與記錄移動次數依賴於步長因子序列的選取

3.使用希爾增量時,希爾排序最差時間複雜度爲$O(n^2)$


交換類排序

2.2.4 冒泡排序法

a) 思想:它重複地走訪過要排序的數列,一次比較兩個元素,如果他們的順序錯誤就把他們交換過來。走訪數列的工作是重複地進行直到沒有再需要交換,也就是說該數列已經排序完成。

b) Java語言描述的關鍵代碼

package exchangeCategorySort;

import java.util.Scanner;

public class BubbleSort {
    public static void main(String[] args) {
        //ArrayList<Integer> arrs = new ArrayList<Integer>();
        Scanner scanner = new Scanner(System.in);
        System.out.println("冒泡排序——請輸入待排序數的個數:");
        int num = scanner.nextInt();
        System.out.println("冒泡排序——請輸入待排數據:");
        Integer[] arr = new Integer[num];
        for(int i = 0; i < num; i++){
            int temp = scanner.nextInt();
            arr[i] = temp;
        }
        scanner.close();
        //arrs.toArray(arr);
        //泛型方法調用
        System.out.println("冒泡排序——排序完成後的數據:");
        new BubbleSort().<Integer>bubbleSortMethod(arr);
        for(Integer in:arr) {
            System.out.println(in);
        }
    }
    /** 
    * TODO(方法功能描述) 冒泡排序核心代碼
    * @param data 待排數據
    * @author zhiman in 2017年10月8日 下午10:14:11 
    */
    public <AnyType extends Comparable<? super AnyType>>
        void bubbleSortMethod(AnyType[] data) {
        //改進算法,設置標誌位
        boolean flag = true;
        for (int i = 0; i < data.length - 1 && flag ; i++) {
            flag = false;
            for (int j = 0; j < data.length - i - 1; j++) {
                if (data[j].compareTo(data[j+1]) > 0) {
                    AnyType temp = data[j+1];
                    data[j+1] = data[j];
                    data[j] = temp;
                    //如果某次循環,沒有交換,則排序完成
                    flag = true;
                }
            }
        }
    }
}

b) 算法分析

1. 上述改進後的冒泡排序算法,當待排數據順序有序時,有最好的時間複雜O(n) ,當待排數據逆序有序時,有最差的時間複雜度O(n2)

2. 冒泡排序是穩定的排序算法


2.2.4 快速排序法

a) 思想:快速排序(quick sort)是對起泡排序的一種改進。通過一趟排序將待排記錄分割成獨立的兩部分,其中一部分記錄的關鍵字均比另一部分記錄的關鍵字小,然後分別對這兩部分記錄繼續進行排序,直到整個序列有序。

b) Java語言描述的關鍵代碼

javapackage exchangeCategorySort;

import java.util.*;

public class QuickSort {
    public static void main(String[] args) {
        List<Integer> arrs = new ArrayList<Integer>();
        Scanner scanner = new Scanner(System.in);
        System.out.println("快速排序——請輸入待排序數的個數:");
        int num = scanner.nextInt();
        System.out.println("快速排序——請輸入待排數據:");
        Integer[] arr = new Integer[num];
        for(int i = 0; i < num; i++){
            int temp = scanner.nextInt();
            arr[i] = temp;
            arrs.add(temp);
        }
        scanner.close();
        //arrs.toArray(arr);
        //泛型方法調用
        System.out.println("快速排序——排序完成後的數據:");

        QuickSort qs = new QuickSort();
        //調用快排算法一
        qs.<Integer>quickSortOne(arr,0,arr.length - 1);
        for(Integer in:arr) {
            System.out.println(in);
        }
        //調用快排算法二
        qs.quickSortTWo(arrs);
        for(Integer in:arrs) {
            System.out.println(in);
        }
    }

    /** 
    * TODO(方法功能描述) 第一種快速排序方法
    * @param data 待排數據
    * @param low 待排數據低下標
    * @param high 待排數據高下標
    * @author zhiman in 2017年10月9日 下午4:17:23 
    */
    public <AnyType extends Comparable<? super AnyType>>
        void quickSortOne(AnyType[] data , int low , int high) {
        int keyElementPosition;
        //此處必須是if判斷,否則無限循環
        if (low < high) {
            keyElementPosition = doPartition(data,low,high);
            //對一次劃分的左邊元素快速排序
            quickSortOne(data,low,keyElementPosition - 1);
            //對一次劃分的右邊元素快速排序
            quickSortOne(data,keyElementPosition + 1,high);
        }
    }

    /** 
    * TODO(方法功能描述) 一次劃分
    * @param data 待排數據
    * @param low 待排數據低下標
    * @param high 待排數據高下標
    * @return 樞紐元素插入位置
    * @author zhiman in 2017年10月9日 下午3:43:00 
    */
    private  <AnyType extends Comparable<? super AnyType>> 
        int doPartition(AnyType[] data , int low , int high) {
        //獲取low high 和(low + high)/2中間元素,並將其置於low所指位置
        getMidian(data,low,high);
        AnyType key = data[low];//選取數組下標爲low元素作爲樞紐
        //直到low = high 時循環結束
        while (low < high) {
            //循環直到找到一個比樞軸元素小的元素
            while ( low < high && key.compareTo( data[high] ) < 0 ) {
                high--;
            }
            data[low] = data[high];
            //循環直到找到一個比樞軸元素大的元素
            while ( low < high && key.compareTo( data[low] ) > 0 ) {
                low++;
            }
            data[high] = data[low];
        }
        data[low] = key;
        return low;
    } 

    /** 
    * TODO(方法功能描述) 一種簡單實現快排的方法
    * @param items List集合
    * @author zhiman in 2017年10月9日 下午8:19:43 
    */
    public void quickSortTWo(List<Integer> items) {
        if (items.size() > 1) {
            List<Integer> smaller = new ArrayList<Integer>();
            List<Integer> same = new ArrayList<Integer>();
            List<Integer> larger = new ArrayList<Integer>();
            //得到樞軸元素
            Integer keyItem = items.get(items.size() / 2);
            for (Integer it:items) {
                if (it < keyItem) {
                    smaller.add(it);
                } else if (it > keyItem) {
                    larger.add(it);
                } else {
                    same.add(it);
                }
            }
            quickSortTWo(smaller);
            quickSortTWo(larger);

            items.clear();
            items.addAll(smaller);
            items.addAll(same);
            items.addAll(larger);

        }
    }
    /** 
    * TODO(方法功能描述) 獲取中值,並將其放到left所指位置
    * @param a 待排數據
    * @param left 待排數據低索引
    * @param right 待排數據高索引
    * @return 樞軸元素
    * @author zhiman in 2017年10月10日 下午3:40:51 
    */
    private <AnyType extends Comparable<? super AnyType>> 
        void getMidian(AnyType[] a, int left, int right){
        int mid = (left + right) / 2;
        if (a[mid].compareTo(a[left]) < 0)
            swap(a,left,mid);
        if (a[right].compareTo(a[left]) < 0)
            swap(a,left,right);
        if (a[right].compareTo(a[mid]) < 0)
            swap(a,mid,right);
        //讓中間值位於下標爲right - 1的位置
        swap(a , mid, left);
    }
    private <AnyType extends Comparable<? super AnyType>> 
        void swap(AnyType[] a, int left, int right) {
        AnyType temp = a[left];
        a[left] = a[right];
        a[right] = temp;
    }

}

c) 算法分析

1. 快速排序是不穩定的排序方法

2. 快速排序平均時間複雜度爲O(nlogn) —犧牲穩定性換來效率提升

3. 當待排序列逆序有序時,快速排序退化爲冒泡排序,有最差時間複雜度O(n2)


選擇類排序

2.2.5 簡單選擇排序法

a) 思想:

第 1 趟選擇: 從 1—n 個記錄中選擇關鍵字最小的記錄,並和第 1 個記錄交換。
第 2 趟選擇:從 2—n 個記錄中選擇關鍵字最小的記錄,並和第 2 個記錄交換。

*
*
*

第 n 趟選擇:從 (n-1)—n 個記錄中選擇關鍵字最小的記錄,並和第 n-1 個記錄交換。

b) Java語言描述的關鍵代碼

package insertCategorySort;

import java.util.ArrayList;
import java.util.Scanner;

/**
* @Description 直接插入排序(基於順序查找)
* @author zhiman in 2017年10月7日 下午5:26:45 [email protected]
* @version V1.0
* 
*/
public class SimpleInsertionSort {


    public static void main(String[] args) {
        ArrayList<Integer> arrs = new ArrayList<Integer>();
        Scanner scanner = new Scanner(System.in);
        System.out.println("請輸入待排序數的個數:");
        int num = scanner.nextInt();
        System.out.println("請輸入待排數據:");
        for(int i = 0; i < num; i++){
            int temp = scanner.nextInt();
            arrs.add(temp);
        }
        scanner.close();
        Integer[] arr = new Integer[num];
        arrs.toArray(arr);
        //泛型方法調用
        System.out.println("排序完成後的數據:");
        new SimpleInsertionSort().<Integer>insertionSort(arr);
        for(Integer in:arr) {
            System.out.println(in);
        }
    }
    /** 
    * TODO(方法功能描述) 直接插入排序核心代碼.
    * @author zhiman in 2017年10月7日 下午5:28:56 
    */
    public  <AnyType extends Comparable<? super AnyType>> 
        void insertionSort(AnyType[] data) {
        //暫存帶排序的元素
        int i;
        for(int pointer = 1; pointer < data.length; pointer++) {
            AnyType temp = data[pointer];
            for (i = pointer; i > 0 /*&& temp.compareTo(data[i - 1]) < 0*/; i--) {
                if (temp.compareTo(data[i-1]) < 0) 
                    data[i] = data[i - 1];
                else 
                    break;
            }
            data[i] = temp;
        }
    }
}

c) 算法分析: 時間複雜度:O(n2) ,且是不穩定的排序法。


2.2.6 堆排序

a) 思想:在大頂堆中,將堆頂和最後一個記錄交換,即得第一趟的結果;再使剩餘n-1個元素的序列重又建成一個堆,則得到n個元素的次大值。如此反覆執行,便能得到一個有序序列,這個過程稱爲堆排序。

b) Java語言描述的關鍵代碼

package selectCategorySort;

import java.util.Scanner;


/**
* @Description 對用數組存儲的堆進行排序
* @author zhiman in 2017年10月10日 下午9:42:08 [email protected]
* @version V1.0
* 
*/
public class HeapSort {
    public static void main(String[] args) {
        //ArrayList<Integer> arrs = new ArrayList<Integer>();
        Scanner scanner = new Scanner(System.in);
        System.out.println("堆排序——請輸入待排序數的個數:");
        int num = scanner.nextInt();
        System.out.println("堆排序——請輸入待排數據:");
        Integer[] arr = new Integer[num];
        for(int i = 0; i < num; i++){
            int temp = scanner.nextInt();
            arr[i] = temp;
        }
        scanner.close();
        //arrs.toArray(arr);
        //泛型方法調用
        System.out.println("堆排序——排序完成後的數據:");
        new HeapSort().<Integer>heapSort(arr);
        for(Integer in:arr) {
            System.out.println(in);
        }
    }
    /** 
    * TODO(方法功能描述) 堆排序關鍵代碼
    * @param data 待排數據
    * @author zhiman in 2017年10月10日 下午9:25:07 
    */
    public <AnyType extends Comparable<? super AnyType>>
        void heapSort(AnyType[] data) {
        //建堆,對於有n個元素的堆,從n/2處開始調整堆,數組從0下標開始,所以此處需再減一
        for (int i = data.length / 2 - 1; i >= 0; i--) {
            percDown(data,i,data.length);
        }
        //刪除堆頂最大元素
        for (int i = data.length - 1; i > 0; i--) {
            //swap(data,0,i)中i代表元素下標
            swap(data,0,i);
            //percDown(data,0,i)中i代表堆中元素個數
            percDown(data,0,i); 
        }
    }
    /** 
    * TODO(方法功能描述) 刪除堆頂元素並重建堆
    * @param a 待排數據
    * @param i 
    * @param n 堆元素個數
    * @author zhiman in 2017年10月10日 下午9:31:13 
    */
    public <AnyType extends Comparable<? super AnyType>>
        void percDown(AnyType[] a,int i, int n) {
        int child;
        AnyType temp;

        for (temp = a[i]; getLeftChild(i) < n; i = child) {
            child = getLeftChild(i);
            //n-1爲數組表示的堆得最後一個元素的下標,讓child指向左右孩子中較大的元素下標
            if ( child != n-1 && a[child].compareTo( a[child + 1] ) < 0 ) {
                child++;
            }
            //將結點的值與該節點左右孩子中較大的值比較,並調整堆
            if( temp.compareTo( a[child] ) < 0) {
                a[i] = a[child];
            } else
                break;
        }
        a[i] = temp;
    }
    /** 
    * TODO(方法功能描述) 得到元素i左孩子下標
    * @param i
    * @return 元素i左孩子下標
    * @author zhiman in 2017年10月10日 下午9:27:24 
    */
    private int getLeftChild (int i) {
        //用數組來存儲堆,堆頂元素下標爲0,所以左孩子下標爲2*i+1;
        return 2 * i + 1;
    }

    /** 
    * TODO(方法功能描述) 交換數組元素
    * @param a
    * @param left
    * @param right
    * @author zhiman in 2017年10月10日 下午9:48:59 
    */
    private <AnyType extends Comparable<? super AnyType>> 
        void swap(AnyType[] a, int left, int right) {
        AnyType temp = a[left];
        a[left] = a[right];
        a[right] = temp;
}
}

c) 算法分析

1. 堆排序最壞情況下,時間複雜度也爲O(nlogn2)

2. 堆排序是不穩定的排序算法。

3. 堆排序相對簡單選擇排序而言犧牲了空間換取效率的提升。


歸併類排序

2.2.7 歸併排序法

a) 思想: 將兩個或兩個以上的有序子序列 “歸併” 爲一個有序序列。

b) Java語言描述的關鍵代碼

package mergeCategorySort;

import java.util.Scanner;


public class MergeSort {
    public static void main(String[] args) {
        //ArrayList<Integer> arrs = new ArrayList<Integer>();
        Scanner scanner = new Scanner(System.in);
        System.out.println("歸併排序——請輸入待排序數的個數:");
        int num = scanner.nextInt();
        System.out.println("歸併排序——請輸入待排數據:");
        Integer[] arr = new Integer[num];
        for(int i = 0; i < num; i++){
            int temp = scanner.nextInt();
            arr[i] = temp;
        }
        scanner.close();
        //arrs.toArray(arr);
        //泛型方法調用
        System.out.println("歸併排序——排序完成後的數據:");
        new MergeSort().<Integer>mergeSort(arr);
        for(Integer in:arr) {
            System.out.println(in);
        }
    }
    /** 
    * TODO(方法功能描述) 重載方法 
    * @param a 待排數據
    * @author zhiman in 2017年10月10日 下午11:18:18 
    */
    public <AnyType extends Comparable<? super AnyType>> 
    void mergeSort(AnyType[] a) {
        @SuppressWarnings("unchecked")
        AnyType[] tempArray = (AnyType[])new Comparable[a.length];
        mergeSort(a, tempArray, 0, a.length - 1);
    }
    /** 
    * TODO(方法功能描述) 歸併排序關鍵代碼
    * @param a 待排數據
    * @param tempArray 暫存數組
    * @param left 下標
    * @param right 下標
    * @author zhiman in 2017年10月10日 下午11:11:45 
    */
    public <AnyType extends Comparable<? super AnyType>> 
        void mergeSort(AnyType[] a, AnyType[] tempArray, int left, int right) {
        if (left < right) {
            int center = (left + right) / 2;
            mergeSort(a, tempArray, left, center);
            mergeSort(a, tempArray, center + 1, right);
            merge(a, tempArray, left, center + 1, right);
        }
    }

    /** 
    * TODO(方法功能描述) 歸併元素
    * @param a 待排數據
    * @param tempArray 暫存數組
    * @param leftPos 左表起始位置
    * @param rightPos 右表起始位置
    * @param rightEnd 右表終止位置
    * @author zhiman in 2017年10月10日 下午11:23:01 
    */
    private <AnyType extends Comparable<? super AnyType>> 
        void merge(AnyType[] a, AnyType[] tempArray, int leftPos, int rightPos, int rightEnd) {
        //左表終止位置
        int leftEnd = rightPos - 1;
        int tempPos = leftPos;
        //元素總個數
        int numElements = rightEnd - leftPos + 1;

        //循環歸併直到兩個表中一個表元素全部歸併到新表
        while (leftPos <= leftEnd && rightPos <= rightEnd) {
            if ( a[leftPos].compareTo( a[rightPos] ) <= 0 ) {
                tempArray[tempPos++] = a[leftPos++];
            } else {
                tempArray[tempPos++] = a[rightPos++];
            }
        }
        //若右表歸併完,則複製左表剩餘元素到tempArray
        while ( leftPos <= leftEnd ) {
            tempArray[tempPos++] = a[leftPos++];
        }
        //若左表歸併完,則複製右表剩餘元素到tempArray
        while ( rightPos <= rightEnd ) {
            tempArray[tempPos++] = a[rightPos++];
        }
        //將tempArray複製到a
        for (int i = 0; i < numElements; i++ , rightEnd--) {
            //why
            a[rightEnd] = tempArray[rightEnd];
        }

    }
}

c) 算法分析

1. 第i趟歸併後,有序子文件長度爲2i,因此對有n個記錄的文件排序,必須做logn2 向上取整趟歸併,每趟歸併所花的時間是O(n) ;所以,二路歸併排序的時間複雜性爲O(nlogn2)

2. 歸併排序是穩定的。


各種排序方法Java源代碼鏈接:各種排序方法Java源代碼鏈接

發佈了24 篇原創文章 · 獲贊 52 · 訪問量 3萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章