java實現9大排序演算法

2021-07-27 14:12:45 字數 3775 閱讀 7713

排序大的分類可以分為兩種:內排序和外排序。

在排序過程中,全部記錄存放在記憶體,則稱為內排序,如果排序過程中需要使用外存,則稱為外排序。

一般來說外排序分為兩個步驟:預處理和合併排序。首先,根據可用記憶體的大小,將外存上含有n個紀錄的檔案分成若干長度為t的子檔案(或段);其次,利用內部排序的方法,對每個子檔案的t個紀錄進行內部排序。這些經過排序的子檔案(段)通常稱為

順串(run),順串生成後即將其寫入外存。這樣在外存上就得到了m個順串(m=[n/t])。最後,對這些順串進行歸併,使順串的長度逐漸增大,直到所有的待排序的機率成為乙個順串為止。

內排序可以分為以下幾類:

(1)、插入排序:直接插入排序、折半插入排序、希爾排序。

(2)、選擇排序:簡單選擇排序、堆排序。

(3)、交換排序:氣泡排序、快速排序。

外排序可以分為一下幾類(既使用內部儲存也使用外部儲存,記憶體不夠時建議使用):

(4)、歸併排序

(5)、基數排序

穩定性:就是能保證排序前兩個相等的資料其在序列中的先後位置順序與排序後它們兩個先後位置順序相同。再簡單具體一點,如果a i == a j,ai 原來在 aj 位置前,排序後 ai  仍然是在 aj 位置前。

不穩定:簡單選擇排序、快速排序、希爾排序、堆排序不是穩定的排序演算法

穩定:氣泡排序、直接插入排序、折半插入排序,歸併排序和基數排序都是穩定的排序演算法。

平均時間複雜度

o(n^2):直接插入排序,簡單選擇排序,氣泡排序。

在資料規模較小時(9w內),直接插入排序,簡單選擇排序差不多。當資料較大時,氣泡排序演算法的時間代價最高。效能為o(n^2)的演算法基本上是相鄰元素進行比較,基           本上都是穩定的。

o(nlogn):快速排序,歸併排序,希爾排序,堆排序。

其中,快排是最好的, 其次是歸併和希爾,堆排序在資料量很大時效果明顯。

•思想:每步將乙個待排序的記錄,按其順序碼大小插入到前面已經排序的字序列的合適位置,直到全部插入排序完為止。

•關鍵問題:在前面已經排好序的序列中找到合適的插入位置。

•方法:

–直接插入排序

–折半插入排序

–希爾排序

圖例:

關鍵**:

private static void directinsertsort(int array) 

}h = h/3;} }

•思想:每趟從待排序的記錄序列中選擇關鍵字最小的記錄放置到已排序表的最前位置,直到全部排完。

•關鍵問題:在剩餘的待排序記錄序列中找到最小關鍵碼記錄。

•方法:

–直接選擇排序

–堆排序

在要排序的一組數中,選出最小的乙個數與第乙個位置的數交換;然後在剩下的數當中再找最小的與第二個位置的數交換,如此迴圈到倒數第二個數和最後乙個數比較為止。

圖例:

關鍵**:

public static void directselectionsort(int array)               }}}

初始時把要排序的數的序列看作是一棵順序儲存的二叉樹,調整它們的儲存序,使之成為乙個 堆,這時堆的根節點的數最大。然後將根節點與堆的最後乙個節點交換。然後對前面(n-1)個數重新調整使之成為堆。依此類推,直到只有兩個節點的堆,並對 它們作交換,最後得到有n個節點的有序序列。堆排序也是一種不穩定的排序演算法。

堆排序優於簡單選擇排序的原因:直接選擇排序中,為了從r[1..n]中選出關鍵字最小的記錄,必須進行n-1次比較,然後在r[2..n]中選出關鍵字最小的記錄,又需要做n-2次比較。事實上,後面的n-2次比較中,有許多比較可能在前面的n-1次比較中已經做過,但由於前一趟排序時未保留這些比較結果,所以後一趟排序時又重複執行了這些比較操作。堆排序可通過樹形結構儲存部分比較結果,可減少比較次數。堆排序的最壞時間複雜度為o(nlogn)。堆序的平均效能較接近於最壞效能。由於建初始堆所需的比較次數較多,所以堆排序不適宜於記錄數較少的檔案。

圖例:建堆:

交換,從堆中踢出最後乙個數:

關鍵**:

public static void buildminheap(int array)

}} return array;

}

分析:

氣泡排序是一種穩定的排序方法。 

•若檔案初狀為正序,則一趟起泡就可完成排序,排序碼的比較次數為n-1,且沒有記錄移動,時間複雜度是o(n)

•若檔案初態為逆序,則需要n-1趟起泡,每趟進行n-i次排序碼的比較,且每次比較都移動三次,比較和移動次數均達到最大值∶o(n2)

•起泡排序平均時間複雜度為o(n2)

選擇乙個基準元素,通常選擇第乙個元素或者最後乙個元素,通過一趟掃瞄,將待排序列分成兩部分,一部分比基準元素小,一部分大於等於基準元素,此時基準元素在其排好序後的正確位置,然後再用同樣的方法遞迴地排序劃分的兩部分。

傳統方法圖例:

關鍵**:

public static void quicksort(int array,int start,int end) 

if(array[i]分析:

快速排序是不穩定的排序。

快速排序的時間複雜度為o(nlogn)。

當n較大時使用快排比較好,當序列基本有序時用快排反而不好。

歸併(merge)排序法是將兩個(或兩個以上)有序表合併成乙個新的有序表,即把待排序序列分為若干個子串行,每個子串行是有序的。然後再把有序子串行合併為整體有序序列。

圖例:

關鍵**:

private static void sort(int array,int low,int high)

}private static void merge(int array, int low, int middle, int high)

//建立十個佇列

list> alist = new arraylist>();

for (int i = 0; i < 10; i++)

//進行times次分配和收集

for (int i = 0; i < times; i++)

//收集

int count = 0;

for (int j = 0; j < 10; j++)}}

return array;

}

分析:

基數排序是穩定的排序演算法。

基數排序的時間複雜度為o(d(n+r)),d為位數,r為基數。

八大排序演算法Java實現

常見的八大排序演算法,它們之間的關係如下 經常碰到這樣一類排序問題 把新的資料插入到已經排好的資料列中。將第乙個數和第二個數排序,然後構成乙個有序序列 將第三個數插入進去,構成乙個新的有序序列。對第四個數 第五個數 直到最後乙個數,重複第二步。首先設定插入次數,即迴圈次數,for int i 1 i...

十大排序演算法(Java實現)

氣泡排序 public static int bubblesort int arr return arr 選擇排序 public static int selectsort int arr swap arr,i,min return arr 插入排序 public static int insert...

八大排序演算法的Java實現

直接插入排序 穩定排序,時間複雜度 o n o n 2 適用於少量元素。基本思想 將乙個元素插入到已排好序的列表中。public static void insertsort int array array j 1 key shell排序 不穩定,o nlogn 基本思想 把整個列表分成若干個子串行...