基于Java語言的排序算法

image.png

各排序代碼如下:

一:交換排序

// 冒泡排序
@Override
public void bubbleSort(int[] data) {
    if (null == data || data.length <= 1) {
        return;
    }
    final int length = data.length;
    int temp = 0;
    // 外層循環(huán)控制比較趟數(shù) (每比較一趟,會確定一個數(shù)的最終位置, 會比較data.length - 1 趟)
    for (int i = 0; i < length - 1; i++) { // 注意下標  結(jié)尾是 length - 1
        // 內(nèi)層循環(huán)是比較第[i]元素與,[i + 1, data.length]中所有元素的比較
        for (int j = 0; j < length - 1 - i; j++) {
            if (data[j + 1] < data[j]) {
                temp = data[j + 1];
                data[j + 1] = data[j];
                data[j] = temp;
            }
        }
    }
}

// 快速排序
@Override
public void quickSort(int[] data) {
    if (null == data || data.length <= 1) {
        return;
    }
    long startTime = System.currentTimeMillis();
    inner_quickSort(data, 0, data.length - 1);
    System.out.println("快速排序時間:" + (System.currentTimeMillis() - startTime));
}

private void inner_quickSort(int[] data, int start, int end) {
    if (start < end) {
        int i = partition(data, start, end);
        inner_quickSort(data, start, i - 1);
        inner_quickSort(data, i + 1, end);
    }
}

private int partition(int[] array, int start, int end) {
    int temp = array[start]; // 用子序的第一個作為基準
    int i = start, j = end;
    while (i < j) {
        // 先遍歷右邊的數(shù)據(jù)
        while (i < j && array[j] > temp) {
            j--;
        }
        if (i < j) {
            array[i] = array[j];
            i++;
        }

        // 再遍歷左邊的數(shù)據(jù)
        while (i < j && array[i] < temp) {
            i++;
        }
        if (i < j) {
            array[j] = array[i];
            j--;
        }
        // array[i] = temp;
    }
    array[i] = temp;
    return i;
}

二:選擇排序

// 簡單選擇排序
@Override
public void simpleSelect(int[] data) {
    if (null == data || data.length <= 1) {
        return;
    }
    final int length = data.length;
    for (int i = 0; i < length; i++) {
        int target = i;
        for (int j = i + 1; j < length; j++) {
            if (data[j] < data[target]) {
                target = j;
            }
        }
        int temp = 0;
        if (target != i) {
            temp = data[target];
            data[target] = data[i];
            data[i] = temp;
        }
    }

}

// 堆排序
@Override
public void heapSort(int[] data) {
    // TODO Auto-generated method stub

}

三: 插入排序

// 直接插入排序
@Override
public void directInsertSort(int[] data) {
    for (int i = 1; i < data.length; i++) {
        inner(data, 1, i);
    }
}

// 希爾排序
@Override
public void shellSort(int[] data) {
    int length = data.length;
    for (int gap = length / 2; gap > 0; gap /= 2) {
        for(int j = gap; j < length; j++) {
            inner(data, gap, j);
        }
    }
}

private void inner(int[] data, int gap, int i) {
    int willInsert = data[i];
    int j;
    for (j = i; j >= gap && data[j - gap] > willInsert; j -= gap) {
        data[j] = data[j - gap];
    }
    data[j] = willInsert;
}

四: 歸并排序

時間復(fù)雜度:O(nlogn)
空間復(fù)雜度:O(N) ,歸并排序需要一個與原數(shù)組相同長度的數(shù)組來做輔助排序。
穩(wěn)定性:是穩(wěn)定的排序算法

@Override
public void mergeSort(int[] data) {
    if (null == data || 1 >= data.length) {
        return;
    }
    sort(data, 0, data.length - 1);
}

private void sort(int[] a, int start, int end) {
    if (start < end) {// 當子序列中只有一個元素時結(jié)束遞歸
        final int mid = (start + end) / 2;// 劃分子序列
        // 對左側(cè)子序列進行遞歸排序
        sort(a, start, mid);
        // 對右側(cè)子序列進行遞歸排序
        sort(a, mid + 1, end);
        // 合并
        merge(a, start, mid, end);
    }
}

// 兩路歸并算法,兩個排好序的子序列合并為一個子序列
private void merge(int[] a, int left, int mid, int right) {
    int[] tmp = new int[a.length];// 輔助數(shù)組
    int p1 = left, p2 = mid + 1, tmpIndex = left;// p1、p2是檢測指針,k是存放指針
    
    // 比較左右兩部分的元素,哪個小就把哪個元素填入tmp中
    while (p1 <= mid && p2 <= right) {
        tmp[tmpIndex++] = a[p1] <= a[p2] ? a[p1++] : a[p2++];
    }

    // 如果第一個序列未檢測完,直接將后面所有元素加到合并的序列中
    // (以下兩個while只有一個會執(zhí)行)
    while (p1 <= mid)
        tmp[tmpIndex++] = a[p1++];

    while (p2 <= right)
        tmp[tmpIndex++] = a[p2++];

    // 把最終的排序的結(jié)果復(fù)制給原數(shù)組
    for (int i = left; i <= right; i++)
        a[i] = tmp[i];
}
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 總結(jié)一下常見的排序算法。 排序分內(nèi)排序和外排序。內(nèi)排序:指在排序期間數(shù)據(jù)對象全部存放在內(nèi)存的排序。外排序:指在排序...
    jiangliang閱讀 1,518評論 0 1
  • 排序的基本概念 在計算機程序開發(fā)過程中,經(jīng)常需要一組數(shù)據(jù)元素(或記錄)按某個關(guān)鍵字進行排序,排序完成的序列可用于快...
    Jack921閱讀 1,569評論 1 4
  • 排序大的分類可以分為兩種:內(nèi)排序和外排序。在排序過程中,全部記錄存放在內(nèi)存,則稱為內(nèi)排序,如果排序過程中需要使用外...
    文哥的學(xué)習(xí)日記閱讀 1,135評論 2 10
  • 概述 排序有內(nèi)部排序和外部排序,內(nèi)部排序是數(shù)據(jù)記錄在內(nèi)存中進行排序,而外部排序是因排序的數(shù)據(jù)很大,一次不能容納全部...
    蟻前閱讀 5,301評論 0 52
  • 題目鏈接難度:中等 類型: 數(shù)組、深度優(yōu)先搜索 班上有 N 名學(xué)生。其中有些人是朋友,有些則不...
    wzNote閱讀 1,463評論 0 1

友情鏈接更多精彩內(nèi)容