插入排序的過程與我們平時抓牌的過程非常類似。每次抓一張排,然後與手上已有的牌逐個進行比較,找到其合適的插入位置。
一、直觀的直接插入排序代碼
完全按照直接插入排序算法來編寫代碼,需要另外開闢一個與原數據相同的存儲空間。
將這個過程量化:假設有原序列有n個數據元素。第一個元素無序插入,因此需要插入n-1次。每次插入過程中,從後往前,遇到比
自己大的就將此大的元素往後移動移位,直到遇到比自己小的,將此元素直接存放到此。如果插入的元素比已經有序的序列最後一
個元素都大的話就無需移動,直接插在末尾位置了。代碼如下:
void InsertSort(int array[], const int arrayCount)
{
int array1[arrayCount];
array1[0] = array[0];
int tailIndex = 0; //已經排好的有序序列的末尾下標
for(int i = 1; i < arrayCount; ++i)
{
if(array[i] > array1[tailIndex]) //比有序序列尾端的數據元素都大,則直接插入
{
tailIndex++;
array1[tailIndex] = array[i];
}
else //否則則要從後往前比較,找到第一個比自己小的元素
{
int j;
for(j = tailIndex; j >= 0; --j)
{
if(array1[j] > array[i])
array1[j + 1] = array1[j]; //往後移動一位
else //如果找到了則退出循環,此時j處元素後面的位置即爲插入位置
break;
}
array1[j + 1] = array[i];
tailIndex++;
}
}
}
二、改進後的插入排序算法代碼
想象插入的過程,我們每次都是將插入元素從後往前逐個與它前面的已經有序的序列進行比較,比較的過程中前面的有序序列可能
會後移,每次移動一個,那麼我們可以將插入元素保存起來,然後將插入元素所在的位置作爲前面有序序列後移的空餘空間,然後
找到插入位置就將保存的元素放到這裏。
以圖爲例:
在插入1的時候,先將1存放到temp中,然後空出一個位置出來了。然後temp與前面的有序序列進行比較,每次比較過程中,大的
數據則往後移動以爲,這裏9>temp,則9後移移位,然後找到temp的插入位置插入數據。
代碼如下:
void InsertSort1(int array[], int arrayCount)
{
int temp;
for(int i = 1; i < arrayCount; ++i)
{
if(array[i] > array[i - 1]) //如果插入元素比前面有序序列的尾端元素都大,就直接插入
break;
temp = array[i]; //保存需要插入的元素
int j;
for(j = i - 1; j >= 0; --j) //往前比較
{
if(array[j] < temp) //找到比插入元素還要小的元素,則j的後一位置爲插入位置
break;
array[j + 1] = array[j]; //否則就將當前元素往後移動一位
}
array[j + 1] = temp;
}
}