直接插入排序(insert sort)
將陣列中的資料分為兩個區域,已排序區間和未排序區間。初始已排序區間只有乙個元素,就是陣列的第乙個元素。插入演算法的核心思想就是取未排序區間中的元素,在已排序區間中從後往前找到最合適的位置將其插入,並保證已排序區間資料一直有序,重複這個過程,直到未排序區間中元素未空,演算法結束。
以上插入排序也包含兩種操作,元素比較和元素移動。當需要將資料 a 插入到已排序區間時,需要拿 a 與已排序區間元素依次比較大小,找到合適的位置,找到插入點之後還需要將插入點之後的元素往後移動才能騰出位置給元素 a。
對於不同的查詢插入點方法(從頭到尾、從尾到頭),元素的比較次數是有區別的。但對於乙個給定的初始序列,移動操作的次數總是固定的,就等於初始逆序度。如上圖,滿有序度是 n*(n-1)/2=15,初始序列的有序度是 5,所以逆序度是 10。插入排序中,資料移動的個數總和也等於 10=3+3+4。
// 插入排序,n表示陣列大小
public
void
insertionsort
(int
arr,
int n)
for(
int i =
1; i < n; i++
)else
} a[j+1]
= value;
// 插入元素
}}
小結:
插入排序是原地排序演算法嗎
是,從實現過程可以明顯看出,插入排序演算法的執行並不需要額外的儲存空間,所有空間複雜度是 o(1)
插入排序是穩定的排序演算法嗎?
是,在插入排序中,對於值相同的元素,可以選擇將後面出現的元素,插入到前面出現元素的後,這樣 就可以保持原有的前後順序不變。
插入排序的時間複雜度是多少?
最好情況:元素是有序的,不需要搬移,只用從尾到頭在有序陣列裡面找插入位置,每次只需要比較一 個資料就能確定插入位置。o(n)
最壞情況:陣列倒序,每次插入都相當於在陣列的第乙個位置插入新的資料,大量移動元素,o(n^2)
平均時間複雜度:對於在陣列中插入乙個資料的平均時間複雜度是 o(n),對於插入排序,每次插入操作 都相當於在陣列中插入乙個資料,迴圈執行 n 次,所以平均時間複雜度是 o(n^2)
應用場景:資料規模小且接近有序
插入排序的優化—希爾排序
也稱為縮小增量排序,與直接插入排序不同,會優先比較距離較遠的元素。是把資料按一定的增量分組,對每組使用直接插入排序演算法,隨著增量逐漸減少,每組數越來越多,直到增量減至1,整個陣列資料被分為一組,演算法終止。
關於gap的取法其實是沒有定論的,但是,大部分會在二分之一到三分之一附近。
詳細**:
public
int[
]shellsort
(int
array)
array[preindex + gap]
= temp;
} gap /=2;
}return array;
}
小結:
應用場景:元素比較凌亂,個數比較多; 要求採用插入排序的思想對這個場景排序
做法:將序列變成有序,將資料變少 ---->分組(gap/3+1)、平均分組、每組應用插入排序
演算法的穩定性:不穩定,看乙個排序演算法是否穩定:該排序演算法在進行的過程中是否跨元素進行交換或 插入,有則不穩定
空間複雜度:o(1);
時間複雜度:
最好(資料有序) o(n)
最壞(比較難構造) o(n^2)
基於比較氣泡排序 時間複雜度O n 2
只操作相鄰的兩個資料,每次冒泡操作都會對相鄰的兩個元素進行比較,看是否滿足大小關係要求,如果不滿足讓它兩互換。一次冒泡會讓至少乙個元素移動到它應該在的位置,重複 n 次,就完成了 n 個資料的排序工作。eg 對於一組資料 4 5 6 3 2 1第一次冒泡的過程 經過了 5 次比較,此時 3 已經在正...
基於比較的快速排序 時間複雜度為O nlogn
快速排序 快排利用的是分治思想。如果要排序陣列中下標從 p 到 r 之間的一組資料,選擇p 到 r 之間的任意乙個資料作為分割槽點pivot。遍歷 p 到 r 之間的資料,將小於pivot的放到左邊,將大於pivot的放到右邊,將pivot放到中間。經過這一步驟後陣列 p 到 r 之間的資料就被分為...
插入排序演算法 時間複雜度
1.插入排序演算法 void sortt int a,int length 插入排序演算法 a j 1 temp 2.演算法的時間複雜度 我們假設計算機執行一行基礎 需要執行一次運算。int afunc void 那麼上面這個方法需要執行 2 次運算 int afunc int n for int ...