演算法導論之插入排序
阿新 • • 發佈:2019-01-08
排序問題
輸入: n個數的一個序列< A1,A2 , … , An >。
輸出: 序列的一個排列< A1’ , A2’ , … , An’ >, 滿足A1’ <= A2’ <= … <= An’ , 或者 A1’>= A2’ >= … >= An’ 。
插入排序
1. 原理簡述
- 在未排序的數中取出一個數(從亂糟糟的牌堆裡拿出一張牌)
- 將它插入到已經排好序的子集的正確位置中(將它插入手中已經排好順序的牌中,得到新的排好順序的牌)
- 再取出一個數,將它插入到正確位置(再從亂糟糟的牌堆裡拿出一張牌)
- 依次類推,直到序列裡所有的數都插入到正確的位置。
2. 虛擬碼
INSERTION_SORT(A)
for j = 2 to A.length
key = A[j]
//insert A[j] into the sorted sequence A[0...j-1]
i = j-1
while i > 0 and A[i] > key
A[i+1] = A[i]
i = i-1
A[i+1] = key
3. 理解虛擬碼
- 假設陣列下標從1 開始,陣列總共有n個數。
- 排序方式是 升序排序
- 對於序列中的第2至最後一個數,我們從取出第j個數(j 從 2 到 n),將其儲存在一個 key 臨時變數中,這樣,第j個位置就‘空’了出來。
- 對於A[0…j-1], 最開始時是[ A1 ], 只有一個數,所以它必定是排好序的。
- 從第 j-1 到 第1 個數,依次和 key 比較,如果大於key ,那就把它搬到右邊的位置。
- 當不再有 大於key 的數時,空出來的位置剛好是最適合key的,將key 插進去,便得到一個新的排好順序的序列。
迴圈執行以上步驟,直到將第n 個數插入到正確的位置。
對於 A[5,2,4,6,1,3] 的排序,過程如下圖所示
4. C語言實現
整型數的插入排序,輸出結果可選擇升序或降序
- 標頭檔案, sort.h
#ifndef __SORT_H__
#define __SORT_H__
void Insert_Sort_Integer(int array[], int length, unsigned char isAscending);
#endif
- C 檔案, sort.c
#include "sort.h"
/* 插入排序 */
void Insert_Sort_Integer(int array[], int length, unsigned char isAscending)
{
int i, j;
int temp;
for (i = 1;i < length; i++)
{
temp = *(array + i);
j = i - 1;
if(isAscending)
{
while (j >= 0 && *(array + j) > temp)
{
array[j + 1] = array[j];
j--;
}
}
else
{
while (j >= 0 && *(array + j) < temp)
{
array[j + 1] = array[j];
j--;
}
}
*(array + j + 1) = temp;
}
}
結語
插入排序屬於原址排序,但它的時間複雜度是O(n^2),和氣泡排序同樣的時間複雜度,效率比較低,使用較少, 後面將介紹 歸併排序,堆排序,快速排序