八種基本的排序演算法
初始時把要排序的n個數的序列看作是一棵 順序儲存的二叉樹(一維陣列儲存二叉樹) ,調整它們的儲存 序,使之成為一個堆,將堆頂元素輸出,得到n 個元素中最小(或最大)的元素,這時堆的根節點的數最小(或者最大)。然後對前面(n-1)個元素重新調整使之成為堆,輸出堆頂元素,得到n 個元素中次小(或次大)的元素。依此類推,直到只有兩個節點的堆,並對它們作交換,最後得到有n個節點的有序序列。稱這個過程為 堆排序 。 因此,實現堆排序需解決兩個問題: (1) 如何將n 個待排序的數建成堆; (2)輸出堆頂元素後,怎樣調整剩餘n-1 個元素,使其成為一個新堆。 2.演算法實現 void Make_Heap(int a[],int end) { int pa,t,tag=1; while(tag) { pa=end/2; tag=0; while(pa>0) { if(a[pa]<a[2*pa]) { t=a[pa]; a[pa]=a[2*pa]; a[2*pa]=t; tag=1; } if(2*pa+1<=end&&a[pa]<a[2*pa+1]) { t=a[pa]; a[pa]=a[2*pa+1]; a[2*pa+1]=t; tag=1; } pa--; } } } void HeapSort(int a[]) { int pa,p; int end=N; while(end>1) { Make_Heap(a,end); //交換頭結點好尾節點 p=a[1]; a[1]=a[end]; a[end]=p; end--; } } 3.演算法效能及其優化 空間複雜度:O(1) 時間複雜度:最壞 O(nlogn ) 穩定性:不穩定 優化:無 八、基數排序(桶排序) 桶排序的基本思想:將陣列分佈到遊戲那數量的桶子裡,每個桶子再個別排序(有可能在使用別的排序演算法或是以遞迴方式繼續使用桶排序進行排序),桶排序是鴿巢排序的一種歸納結果。當要被排序的陣列內的數值是均勻分配的時候,桶排序使用線性時間(O(n)).但桶排序並不是比較排序,他不受到O(nlogn)下限的影響 簡單來說,就是把資料分組,放在一個個的桶中,然後對每個桶裡面的在進行排序。 例如要對大小為[1..1000]範圍內的n個整數A[1..n]排序 , 首先,可以把桶設為大小為10的範圍,具體而言,設集合B[1]儲存[1..10]的整數,集合B[2]儲存 (10..20]的整數,……集合B[i]儲存( (i-1)*10, i*10]的整數,i = 1,2,..100。總共有 100個桶。 然後,對A[1..n]從頭到尾掃描一遍,把每個A[i]放入對應的桶B[j]中。 再對這100個桶中每個桶裡的數字排序,這時可用冒泡,選擇,乃至快排,一般來說 任 何排序法都可以。 最後,依次輸出每個桶裡面的數字,且每個桶中的數字從小到大輸出,這 樣就得到所有數字排好序的一個序列了。 假設有n個數字,有m個桶,如果數字是平均分佈的,則每個桶裡面平均有n/m個數字。如果 對每個桶中的數字採用快速排序,那麼整個演算法的複雜度是 O(n + m * n/m*log(n/m)) = O(n + nlogn - nlogm) 從上式看出,當m接近n的時候,桶排序複雜度接近O(n) 當然,以上覆雜度的計算是基於輸入的n個數字是平均分佈這個假設的。這個假設是很強的 ,實際應用中效果並沒有這麼好。如果所有的數字都落在同一個桶中,那就退化成一般的排序了。 前面說的幾大排序演算法 ,大部分時間複雜度都是O(n2),也有部分排序演算法時間複雜度是O(nlogn)。而桶式排序卻能實現O(n)的時間複雜度。但桶排序的缺點是: 1)首先是空間複雜度比較高,需要的額外開銷大。排序有兩個陣列的空間開銷,一個存放待排序陣列,一個就是所謂的桶,比如待排序值是從0到m-1,那就需要m個桶,這個桶陣列就要至少m個空間。 2)其次待排序的元素都要在一定的範圍內等等。 桶式排序是一種分配排序。分配排序的特定是不需要進行關鍵碼的比較,但前提是要知道待排序列的一些具體情況。
分配排序的基本思想: 說白了就是進行多次的桶式排序。 基數排序過程無須比較關鍵字,而是通過“分配”和“收集”過程來實現排序。它們的時間複雜度可達到線性階:O(n)。 例項: 撲克牌中52 張牌,可按花色和麵值分成兩個欄位,其大小關係為: 花色: 梅花< 方塊< 紅心< 黑心 面值: 2 < 3 < 4 < 5 < 6 < 7 < 8 < 9 < 10 < J < Q < K < A 若對撲克牌按花色、面值進行升序排序,得到如下序列:
即兩張牌,若花色不同,不論面值怎樣,花色低的那張牌小於花色高的,只有在同花色情況下,大小關係才由面值的大小確定。這就是多關鍵碼排序。 為得到排序結果,我們討論兩種排序方法。 方法1 :先對花色排序,將其分為4 個組,即梅花組、方塊組、紅心組、黑心組。再對每個組分別按面值進行排序,最後,將4 個組連線起來即可。 方法2 :先按13 個面值給出13 個編號組(2 號,3 號,...,A 號),將牌按面值依次放入對應的編號組,分成13 堆。再按花色給出4 個編號組(梅花、方塊、紅心、黑心),將2號組中牌取出分別放入對應花色組,再將3 號組中牌取出分別放入對應花色組,……,這樣,4 個花色組中均按面值有序,然後,將4 個花色組依次連線起來即可。 設n 個元素的待排序列包含d 個關鍵碼{k1,k2,…,kd},則稱序列對關鍵碼{k1,k2,…,kd}有序是指:對於序列中任兩個記錄r[i]和r[j](1≤i≤j≤n)都滿足下列有序關係: 其中k1 稱為最主位關鍵碼,kd 稱為最次位關鍵碼 。 兩種多關鍵碼排序方法: 多關鍵碼排序按照從最主位關鍵碼到最次位關鍵碼或從最次位到最主位關鍵碼的順序逐次排序,分兩種方法: 最高位優先(Most Significant Digit first)法,簡稱MSD 法 : 1)先按k1 排序 分組 ,將序列分成若干子序列,同一組序列的記錄中,關鍵碼k1 相等。 2)再對各組按k2 排序分成子組,之後,對後面的關鍵碼繼續這樣的排序分組,直到按最次位關鍵碼kd 對各子組排序後。 3)再將各組連線起來,便得到一個有序序列。撲克牌按花色、面值排序中介紹的方法一即是MSD 法。 最低位優先(Least Significant Digit first)法,簡稱LSD 法 : 1) 先從kd 開始排序,再對kd-1進行排序,依次重複,直到按k1排序分組分成最小的子序列後。 2) 最後將各個子序列連線起來,便可得到一個有序的序列, 撲克牌按花色、面值排序中介紹的方法二即是LSD 法。
基於LSD方法的鏈式基數排序的基本思想 “多關鍵字排序”的思想實現“單關鍵字排序”。對數字型或字元型的單關鍵字,可以看作由多個數位或多個字元構成的多關鍵字,此時可以採用“分配-收集”的方法進行排序,這一過程稱作基數排序法,其中每個數字或字元可能的取值個數稱為基數。比如,撲克牌的花色基數為4,面值基數為13。在整理撲克牌時,既可以先按花色整理,也可以先按面值整理。按花色整理時,先按紅、黑、方、花的順序分成4摞(分配),再按此順序再疊放在一起(收集),然後按面值的順序分成13摞(分配),再按此順序疊放在一起(收集),如此進行二次分配和收集即可將撲克牌排列有序。 基數排序: 是按照低位先排序,然後收集;再按照高位排序,然後再收集;依次類推,直到最高位。有時候有些屬性是有優先順序順序的,先按低優先順序排序,再按高優先順序排序。最後的次序就是高優先順序高的在前,高優先順序相同的低優先順序高的在前。基數排序基於分別排序,分別收集,所以是穩定的。 演算法實現: Void RadixSort(Node L[],length,maxradix) { int m,n,k,lsp; k=1;m=1; int temp[10][length-1]; Empty(temp); //清空臨時空間 while (k<maxradix) //遍歷所有關鍵字 { for ( int i=0;i<length;i++) //分配過程 { if (L[i]<m)
相關推薦
八種常見排序演算法的比較和實現
首先排序演算法大的可以分為: 1、關鍵字比較 2、非關鍵字比較 關鍵字比較 關鍵字比較就是通過關鍵字之間的比較和移動,從而使整個序列有序, 而關鍵字比較的演算法,又可以像下面這樣劃分: 對於排序演算法之間的比較,無異於時間複雜度和空間複雜度。 從上表可以看出: 1、從平均時
Java種八種常用排序演算法
目錄: 1.直接插入排序 2.希爾排序 3.簡單選擇排序 4.堆排序 5.氣泡排序 6.快速排序 7.歸併排序 8.基數排序 1. 直接插入排序 經常碰到這樣一類排序問題:把新的資料插入到已經排好的資料列中。 將第一個數和第二個數排序,然後構成一個有序序列 將第三個數插
八種常用排序演算法(Java)
01演算法分類 02時間複雜度 03相關概念 穩定:如果a原本在b前面,而a=b,排序之後a仍然在b的前面。 不穩定:如果a原本在b的前面,而a=b,排序之後a可能會出現在b的後面。 時間複雜度:對排序資料的總的操作次數。反映當n變化時,操作次數呈現什麼規律。
八種經典排序演算法和java實現
文章目錄 演算法概述 演算法分類 演算法複雜度 相關概念 1.氣泡排序(Bubble Sort)
剖析八種經典排序演算法
排序(Sorting) 是計算機程式設計中的一種重要操作,它的功能是將一個數據元素(或記錄)的任意序列,重新排列成一個關鍵字有序的序列。 我整理了以前自己所寫的一些排序演算法結合網上的一些資料,共介紹8種常用的排序演算法,希望對大家能有所幫助。 八種排序
使用Java實現八種基本排序
插入排序、選擇排序、氣泡排序、希爾排序、堆排序、快速排序、歸併排序、基數排序 import java.util.ArrayList; import java.util.List; /** * 排序演算法主類 * * @author eric */ class SortArray {
九種基本排序演算法總結
排序分類: 1、插入排序:直接插入排序,二分法插入排序,希爾排序; 2、選擇排序:簡單選擇排序,堆排序; 3、交換排序:氣泡排序,快速排序; 4、歸併排序; 5、基數排序; (1)直接插入排序:(穩定排序) 基本思想:將每個待排序的記錄,按照其順序碼的大小插入到前
7種基本排序演算法--java實現
7種基本排序演算法有:直接插入排序、希爾排序;直接選擇排序、堆排序;氣泡排序、快速排序;歸併排序。實現如下:import java.util.Arrays; public class SortAlogrithm { public static void main(St
用 Java 實現的八種常用排序演算法
> 八種排序演算法可以按照如圖分類 ![](https://img2020.cnblogs.com/blog/1759254/202010/1759254-20201013141619825-490940992.png) ## 交換排序 所謂交換,就是序列中任意兩個元素進行比較,根據比較結果來交
八種基本的排序演算法
一.、直接插入排序演算法(陣列儲存) 1.n個待排元素,分成兩部分,有序部分和無序部分 2.初始:有序段:a[0] 無序段:a[1]--a[n] 3.演算法實現思想 從無序中取出一個元素a[i]和有序區間元素進
八種常見的演算法排序
一、排序演算法的分類(列舉7種): 1.氣泡排序 2.選擇排序 3.插入排序 4.快速排序 5.歸併排序 (歸併排序需要額外的記憶體空間來儲存資料,其他的方式都是在原來資料上做交換) 6.希爾排序 7.堆排序 1、最基礎的排序——氣泡排序 (時間複雜度
幾種基本排序算法總結
子序列 system aop 大於等於 != pri i++ index 元素移動 以下均采用從小到大排序: 1.選擇排序算法 個人覺得選擇排序算法是容易理解的排序算法,即從n個元素中選擇最小的一個元素與第一個元素交換,再將除第一個元素之外的n-1個元素找到最小的一
Java八種基本類型及其包裝類總結
HA class byte 及其 int pos log character 編譯 原始類型 包裝類 原始類型所占的字節數 short Short 2個字節 int Integer
Java學習筆記四:Java的八種基本數據類型
text 封裝 image 情況 p s 浮點數 align 不容易 字符 Java的八種基本數據類型 Java語言提供了八種基本類型。六種數字類型(四個整數型,兩個浮點型),一種字符類型,還有一種布爾型。 Java基本類型共有八種,基本類型可以分為三類,字符類
Java語言中八種基本類型對應的?包裝類類型
int str2 ger pan 轉換成 方法 print 基本 binary 八種基本類型對應的包裝類類型 byte Byte int Integer char
Java四類八種基本數據類型
都是 spa ng- arc oat 一個 9.png 比較 離散 Java基本數據類型就8種,記住就好了。除了這些都是引用型的了。 第一類:邏輯型boolean 第二類:文本型char 第三類:整數型(byte、short、int、long) char類型占2
資料結構與演算法JavaScript描述讀書筆記(基本排序演算法)
前提準備 //自動生成陣列的函式,n:整數個數,數字在l-r之間 function setData(n,l,r){ var dataStore = []; for(var i=0;i<n;i++){ dataStore[i] = Math.floor(
基本排序演算法-java實現
最近重新學習了排序演算法,之前每次看完當時理解了,但是過一段時間就又忘了,尤其是程式碼,如果放一段時間有很多base case不知道怎麼寫了,所以還是應該詳細的解讀一下再不斷了敲程式碼才能理解比較深刻。 1.氣泡排序(bubble sort) 氣泡排序是一種簡單的排序演算法。其基本思
基本排序演算法的總結
# 插入排序 public static int[] insertSort2(int[] arr) { if (arr.length < 2 || arr == null) { return arr; } // 假設
一張圖教你看懂Java的八種基本資料型別
String和Integer不是Java的八種基本資料型別。char只能儲存一個字元(用單引號),String能夠儲存多個字元(用雙引號)。String屬於final類,定義的是物件,Integer 是 java 為 int 提供的封裝類。int 的預設值為 0,