0. 數據結構圖文解析系列
1. 插入排序簡介
插入排序是一種簡單直觀的排序算法,它也是基於比較的排序算法。它的工作原理是通過不斷擴張有序序列的范圍,對於未排序的數據,在已排序中從后向前掃描,找到相應的位置並插入。插入排序在實現上通常采用就地排序,因而空間復雜度為O(1)。在從后向前掃描的過程中,需要反復把已排序元素逐步向后移動,為新元素提供插入空間,因此插入排序的時間復雜度為O(n^2);
2. 直接插入排序圖解
一般來說,插入排序都采用在數組上就地排序實現。具體算法描述如下:
- 從第一個元素開始,該元素可以認為已經被排序
- 取出下一個元素,在已經排序的元素序列中從后向前掃描
- 如果該元素(已排序)大於新元素,將該元素移到下一位置
- 重復步驟3,直到找到已排序的元素小於或者等於新元素的位置
- 將新元素插入到該位置后
- 重復步驟2~5
假設我們要對數組{12,4,5,2,6,14}進行插入排序,排序過程為:
2.1. 代碼實現
template <typename T>
void InsertSort(T array[],int length)
{
if (array == nullptr || length < 0)
return;
int i, j;
for (i = 1; i < length; i++)
{
if (array[i]<array[i - 1])
{
int temp = array[i];
for (j = i - 1; array[j]>temp; j--) //元素后移
{
array[j + 1] = array[j];
}
array[j+1] = temp; //在合適的位置上出入元素
}
}
}
2.2. 復雜度分析
- 插入排序的最好情況是數組已經有序,此時只需要進行n-1次比較,時間復雜度為O(n);
- 最壞情況是數組逆序排序,此時需要進行n(n-1)/2次比較以及n-1次賦值操作(插入);
- 平均來說插入排序算法的復雜度為O(n^2)。
插入排序不適合對大量數據進行排序應用,但排序數量級小於千時插入排序的效率還不錯,可以考慮使用。插入排序在STL的sort算法和stdlib的qsort算法中,都將插入排序作為快速排序的補充,用於少量元素的排序(通常為8個或以下)。
直接插入排序采用就地排序,空間復雜度為O(1).
2.3. 穩定性
直接插入排序是穩定的,不會改變相同元素的相對順序。
3. 二分查找插入排序
上面的插入排序實現中,為了找到元素的合適的插入位置,我們采用從后到前遍歷的順序查找進行比較,為了減少比較的次數,我們可以換種查找策略:采用二分查找。
我們定義一個二分查找函數,函數返回插入位置的下標:
/*二分查找函數,返回插入下標*/
template <typename T>
int BinarySearch(T array[], int start, int end, T k)
{
while (start <= end)
{
int middle = (start + end) / 2;
int middleData = array[middle];
if (middleData > k)
{
end = middle - 1;
}
else
start = middle + 1;
}
return start;
}
//二叉查找插入排序
template <typename T>
void InsertSort(T array[], int length)
{
if (array == nullptr || length < 0)
return;
int i, j;
for (i = 1; i < length; i++)
{
if (array[i]<array[i - 1])
{
int temp = array[i];
int insertIndex = BinarySearch(array, 0,i, array[i]);//使用二分查找在有序序列中進行查找,獲取插入下標
for (j = i - 1; j>=insertIndex; j--) //移動元素
{
array[j + 1] = array[j];
}
array[insertIndex] = temp; //插入元素
}
}
}
3.2. 復雜度分析
我們這個二分查找的算法並不會因為等於某一個值而停止查找,它將查找整個序列直到start<=end條件不滿足而得到插入的位置,所以對於長度為n的數組來說,比較次數為log2n ,時間復雜度為O(log2n)。二分插入排序的主要操作為比較+后移賦值,則:
- 最壞情況:每次都在有序序列的起始位置插入,則整個有序序列的元素需要后移,時間復雜度為O(n^2)
- 最好情況:待排序數組本身就是正序的,每個元素所在位置即為它的插入位置,此時時間復雜度僅為比較時的時間復雜度,為O(log2n)
- 平均情況:O(n^2)
空間復雜度上, 二分插入排序也是就地排序算法,它的空間復雜度為O(1).
3.3. 穩定性
二分插入排序是穩定的。元素的相對順序在排序后不會被改變。
原創文章,轉載請注明: http://www.cnblogs.com/QG-whz/p/5194569.html