排序演算法是《資料結構與演算法》中最基本的演算法之一。
穩定:如果a原本在b前面,而a=b,排序之後a仍然在b的前面;
不穩定:如果a原本在b的前面,而a=b,排序之後a可能會出現在b的後面;
內排序:所有排序操作都在記憶體中完成;
外排序:由於資料太大,因此把資料放在磁碟中,而排序通過磁碟和記憶體的資料傳輸才能進行;
時間複雜度:乙個演算法執行所耗費的時間。
空間複雜度:執行完乙個程式所需記憶體的大小。
排序演算法可以分為內部排序和外部排序,內部排序是資料記錄在記憶體中進行排序,而外部排序是因排序的資料很大,一次不能容納全部的排序記錄,在排序過程中需要訪問外存。常見的內部排序演算法有:插入排序、希爾排序、選擇排序、氣泡排序、歸併排序、快速排序、堆排序、基數排序等。用一張圖概括:
n: 資料規模
k: 「桶」的個數
in-place: 占用常數記憶體,不占用額外記憶體
out-place: 占用額外記憶體
氣泡排序(bubble sort)也是一種簡單直觀的排序演算法。它重複地走訪過要排序的數列,一次比較兩個元素,如果他們的順序錯誤就把他們交換過來。走訪數列的工作是重複地進行直到沒有再需要交換,也就是說該數列已經排序完成。這個演算法的名字由來是因為越小的元素會經由交換慢慢"浮"到數列的頂端。
氣泡排序還有一種優化演算法,就是立乙個 flag,當在一趟
遍歷中元素沒有發生交換,則證明該序列已經有序。但這種改進對於提公升效能來說並沒有什麼太大作用。
演算法分析
最佳情況:t(n) = o(n) 最差情況:t(n) = o(n2) 平均情況:t(n) = o(n2)
演算法步驟
比較相鄰的元素。如果第乙個比第二個大,就交換他們兩個。
對每一對相鄰元素作同樣的工作,從開始第一對到結尾的最後一對。這步做完後,最後的元素會是最大的數。
針對所有的元素重複以上的步驟,除了最後乙個。
持續每次對越來越少的元素重複上面的步驟,直到沒有任何一對數字需要比較。
例子:粗體部分為有序
陣列:9,5,6,8,2,7,3,4,1
第1次比較:5,6,8,2,7,3,4,1,9
第2次比較:5,6,2,7,3,4,1,8,9
第3次比較:5,2,6,3,4,1,7,8,9
第4次比較:2,5,3,4,1,6,7,8,9
第5次比較:2,3,4,1,5,6,7,8,9
第6次比較:2,3,1,4,5,6,7,8,9
第7次比較:2,1,3,4,5,6,7,8,9
第8次比較:1,2,3,4,5,6,7,8,9
第8次比較:1,2,3,4,5,6,7,8,9
選擇排序是一種簡單直觀的排序演算法,無論什麼資料進去都是 o(n²) 的時間複雜度。所以用到它的時候,資料規模越小越好。唯一的好處可能就是不占用額外的記憶體空間了吧。
演算法分析
最佳情況:t(n) = o(n2) 最差情況:t(n) = o(n2) 平均情況:t(n) = o(n2)
演算法步驟
首先在未排序序列中找到最小(大)元素,存放到排序序列的起始位置。
再從剩餘未排序元素中繼續尋找最小(大)元素,然後放到已排序序列的末尾。
重複第二步,直到所有元素均排序完畢。
例子:粗體部分為有序
陣列:5,2,4,6,1,3
第一次排序:1,5,2,4,6,3
第一次排序:1,2,5, 4,6,3
第一次排序:1,2,3,5,4,6
第一次排序:1,2,3,4, 5,6
第一次排序:1,2,3,4,5,6,
第一次排序:1,2,3,4,5,6,
插入排序的**實現雖然沒有氣泡排序和選擇排序那麼簡單粗暴,但它的原理應該是最容易理解的了,因為只要打過撲克牌的人都應該能夠秒懂。插入排序是一種最簡單直觀的排序演算法,它的工作原理是通過構建有序序列,對於未排序資料,在已排序序列中從後向前掃瞄,找到相應位置並插入。
插入排序和氣泡排序一樣,也有一種優化演算法,叫做拆半插入。
演算法分析
最佳情況:t(n) = o(n) 最壞情況:t(n) = o(n2) 平均情況:t(n) = o(n2)
演算法步驟
將第一待排序序列第乙個元素看做乙個有序序列,把第二個元素到最後乙個元素當成是未排序序列。
從頭到尾依次掃瞄未排序序列,將掃瞄到的每個元素插入有序序列的適當位置。(如果待插入的元素與有序序列中的某個元素相等,則將待插入元素插入到相等元素的後面。)
陣列:9,7,8,2,5,1,3,6,4
第一次排序:9,7,8,2,5,1,3,6,4
第一次排序:7,9,8,2,5,1,3,6,4
第一次排序:7,8,9,2,5,1,3,6,4
第一次排序:2,7,8,9,5,1,3,6,4
第一次排序:2,5,7,8,9,1,3,6,4
第一次排序:1,2,5,7,8,9,3,6,4
第一次排序:1,2,3,5,7,8,9,6,4
第一次排序:1,2,3,4,5,7,8,9,6
第一次排序:1,2,3,4,5,6,7,8,9希爾排序,也稱遞減增量排序演算法,是插入排序的一種更高效的改進版本。但希爾排序是非穩定排序演算法。
希爾排序是基於插入排序的以下兩點性質而提出改進方法的:
插入排序在對幾乎已經排好序的資料操作時,效率高,即可以達到線性排序的效率;但插入排序一般來說是低效的,因為插入排序每次只能將資料移動一位;
希爾排序的基本思想是:先將整個待排序的記錄序列分割成為若干子串行分別進行直接插入排序,待整個序列中的記錄"基本有序"時,再對全體記錄進行依次直接插入排序。
演算法分析
最佳情況:t(n) = o(nlog2 n) 最壞情況:t(n) = o(nlog2 n) 平均情況:t(n) =o(nlog2n)
演算法步驟
選擇乙個增量序列 t1,t2,……,tk,其中 ti > tj, tk = 1;
按增量序列個數 k,對序列進行 k 趟排序;
每趟排序,根據對應的增量 ti,將待排序列分割成若干長度為 m 的子串行,4. 分別對各子表進行直接插入排序。僅增量因子為 1 時,整個序列作為乙個表來處理,表長度即為整個序列的長度。
經典排序演算法 冒泡,選擇,插入排序
基本思想 兩個數比較大小,較大的數下沉,較小的數冒起來.演算法描述 從小到大排序 比較相鄰元素.如果第乙個比第二個大,就交換它們兩個 對每一對相鄰元素做相同的工作,從開始第一對到結尾的最後一對 針對所有元素重複以上的步驟,除了最後乙個 重複步驟1 3,直到排序完成.演示 實現 public stat...
排序演算法之「選擇排序 氣泡排序 插入排序」
上午上課老師通過兩個神似的三角形,講了氣泡排序和選擇排序的區別和聯絡在 恰好下午看到了這樣的一寫關於該排序演算法的一些資料,想了想還是決定試一試,因為出來混總是要還的。就是使一串記錄,按照其中某個或者某個關鍵字的大小,遞增或遞減的排列起來的演算法。它應用在大量資料處理方面,乙個優秀的演算法可以節省大...
排序演算法之 氣泡排序,插入排序,選擇排序
顧名思義 小的數一點一點向前冒,最終有序 時間複雜度 o n 2 public static void bubblesort int arr for int i arr.length 1 i 0 i public static void swap int arr,int i,int j 基本思想 每...