插入排序的过程与我们平时抓牌的过程非常类似。每次抓一张排,然后与手上已有的牌逐个进行比较,找到其合适的插入位置。
一、直观的直接插入排序代码
完全按照直接插入排序算法来编写代码,需要另外开辟一个与原数据相同的存储空间。
将这个过程量化:假设有原序列有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;
}
}