- 冒泡排序
- 插入排序
- 插入排序和冒泡排序分析
冒泡排序
冒泡排序(英語:Bubble Sort怜械,臺灣另外一種譯名為:泡沫排序)是一種簡單的排序算法。它重復(fù)地走訪過要排序的數(shù)列成洗,一次比較兩個(gè)元素摧茴,如果他們的順序錯誤就把他們交換過來。走訪數(shù)列的工作是重復(fù)地進(jìn)行直到?jīng)]有再需要交換饲梭,也就是說該數(shù)列已經(jīng)排序完成。盡管這個(gè)算法是最簡單了解和實(shí)現(xiàn)的排序算法之一焰檩,但它對于包含大量的元素的數(shù)列排序是很沒有效率的憔涉。
冒泡排序算法的運(yùn)作如下:
- 比較相鄰的元素。如果第一個(gè)比第二個(gè)大锅尘,就交換他們兩個(gè)监氢。
- 對每一對相鄰元素作同樣的工作布蔗,從開始第一對到結(jié)尾的最后一對藤违。這步做完后,最后的元素會是最大的數(shù)纵揍。
- 針對所有的元素重復(fù)以上的步驟顿乒,除了最后一個(gè)。
- 持續(xù)每次對越來越少的元素重復(fù)上面的步驟泽谨,直到?jīng)]有任何一對數(shù)字需要比較璧榄。
冒泡排序如果能在內(nèi)部循環(huán)第一次運(yùn)行時(shí)特漩,使用一個(gè)旗標(biāo)來表示有無需要交換的可能,也可以把最壞情況下的復(fù)雜度降低到{O(n)}
在這個(gè)情況骨杂,已經(jīng)排序好的數(shù)列就無交換的需要涂身。
- 最壞時(shí)間復(fù)雜度
- 最優(yōu)時(shí)間復(fù)雜度
- 平均時(shí)間復(fù)雜度
空間復(fù)雜度
總共{O(n)}
需要輔助空間{O(1)}穩(wěn)定的排序
冒泡排序的動態(tài)圖:
Java代碼實(shí)現(xiàn):
package cc;
public class BubbleSort {
public static void bubblesort(int[] a) {
bubblesort(a, 0, a.length-1);
}
private static void bubblesort(int[] a, int left, int right) {
for(int p=right;p>=left;p--) {
int flag = 0;
for(int i=0;i<p;i++) {
if(a[i] > a[i+1]) {
swap(a, i, i+1);
flag = 1;
}
}
if(flag == 0)
break;
}
}
private static void swap(int[] a, int i, int j) {
int temp = a[i];
a[i] = a[j];
a[j] = temp;
}
}
插入排序
類似于摸牌的過程
插入排序(英語:Insertion Sort)是一種簡單直觀的排序算法。它的工作原理是通過構(gòu)建有序序列搓蚪,對于未排序數(shù)據(jù)蛤售,在已排序序列中從后向前掃描,找到相應(yīng)位置并插入妒潭。插入排序在實(shí)現(xiàn)上悴能,通常采用in-place排序(即只需用到O(1)的額外空間的排序),因而在從后向前掃描過程中雳灾,需要反復(fù)把已排序元素逐步向后挪位漠酿,為最新元素提供插入空間。
算法描述:
- 從第一個(gè)元素開始谎亩,該元素可以認(rèn)為已經(jīng)被排序
- 取出下一個(gè)元素炒嘲,在已經(jīng)排序的元素序列中從后向前掃描
- 如果該元素(已排序)大于新元素,將該元素移到下一位置
- 重復(fù)步驟3团驱,直到找到已排序的元素小于或者等于新元素的位置
- 將新元素插入到該位置后
- 重復(fù)步驟2~5
如果比較操作的代價(jià)比交換操作大的話摸吠,可以采用二分查找法來減少比較操作的數(shù)目。該算法可以認(rèn)為是插入排序的一個(gè)變種嚎花,稱為二分查找插入排序寸痢。
- 最壞時(shí)間復(fù)雜度
- 最優(yōu)時(shí)間復(fù)雜度
- 平均時(shí)間復(fù)雜度
空間復(fù)雜度
總共{O(n)}
需要輔助空間{ O(1)}穩(wěn)定的排序
插入排序動態(tài)圖:
Java代碼
package cc;
public class InsertSort {
public static void insertsort(int[] a) {
insertsort(a, 0, a.length-1);
}
private static void insertsort(int[] a, int left , int right) {
int j;
for(int p = left+1;p<=right;p++) {
int temp = a[p];
for(j=p;j>left && a[j-1] > temp;j--)
a[j] = a[j-1];
a[j] = temp;
}
}
}
插入排序和冒泡排序分析
首先我們引入逆序?qū)Φ母拍?/p>
對于下標(biāo)i<j,如果A[i]>A[j]紊选,則稱(i,j)是一對逆序?qū)?inversion)
交換2個(gè)相鄰元素正好消去1個(gè)逆序?qū)Γ?/strong>
給定初始序列{34, 8, 64, 51,32, 21}啼止,冒泡排序和插入排序分別需要多少次元素交換才能完成?
交換次數(shù)就是逆序?qū)Φ拇螖?shù)兵罢,都是9次
插入排序: T(N, I) = O( N+I )献烦,如果序列基本有序,則插入排序簡單且高效
定理:任意N個(gè)不同元素組成的序列平均具有N ( N - 1 ) / 4 個(gè)逆序?qū)Α?/p>
定理:任何僅以交換相鄰兩元素來排序的算法卖词,其平均時(shí)間復(fù)雜度為 ( N2 ) 巩那。 這意味著:要提高算法效率,我們
- 每次消去不止1個(gè)逆序?qū)Γ?/li>
- 每次交換相隔較遠(yuǎn)的2個(gè)元素此蜈!
這就是希爾排序的由來即横。