您的位置:首页 > 其它

[闭目洞察算法系列之二]插入排序三种实现

2017-08-12 08:03 197 查看
直接插入排序的思想是:将一个待排序的数字按照指定的排序规则,插入到一个前面已经排好序的的子序列中, 从而形成一个新的子序列,等待下一个数字的插入, 直至所有数字排序结束。

假设有数组a[0 ... n - 1], 排序流程为:

a[0]位第一个有序子序列, a[1 ... n -1]为无序序列,令i = 1。
将a[i]插入到指定位置, 插入后形成a[0 ... i] 有序子序列。
i++, 重复步骤2,
直至整个数组有序, 即i == n -1


根据上述思路, 下面写出代码(从小到大排序),

void InsertSortA(int *array, int len)
{
    if (array == nullptr || len < 0)
    {
        return;
    }
    
    int curr,before,k;
    
    for (int curr = 1; curr < len; ++curr) //遍历比较 array[1]到 array[len -1]
    {
        for (before = curr - 1; before >=0; before--) //遍历比较待插数据与有序子序列中的元素,寻找比array[curr]小的元素(左面比右面小即停止)
        {
            if (array[before] < array[curr])
            {
                break;
            }
        }
        
        if (before != curr -1)
        {
            //遍历之后发现before未变化,说明array[curr]比子序列最后一个元素都大,那么当前curr位置就是该插入的位置,比较下一个元素array[curr+1]即可
            //如果发现变化了,就说明中间有一个合适的位置,此时就需要将那个位置至子序列末尾的元素全部后移一位,从而将array[curr]插到该位置。
            int tmp = array[curr];
            for (k = curr - 1; k > before; k--)
            {
                array[k +1] = array[k];
            }
            array[k +1] = tmp;
        }
    }
}


上述代码有些啰嗦, 可以将搜索目标位置与数据后移两部分合并,即每次先比较array[i]和array[i -1], 若array[i] >= array[i -1], 说明当前元素大于或等于前面子序列中任意元素,则直接跳过,比较下一个元素即可。反之,则进入后移流程: j=i - 1, tmp = array[i], 然后一边向后移动数据,一边向前搜索位置,直至array[j] < tmp, array[j+1] = tmp

void InsertSortB(int *array, int len)
{
    if (array == nullptr || len < 0)
    {
        return;
    }
    for (int curr = 1; curr < len; ++curr)
    {
        if (array[curr] < array[curr-1])
        {
            int tmp = array[curr];
            for (before = curr -1; before >=0 && array[before] > tmp; before--)
            {
                array[before+1] = arry[before];
            }
            
            array[before+1] = tmp;
        }
    }
}


第三种实现的思想是: 将array[j]插入到array[0 ... j-1]步骤进行改写, 使用数据交换代替数据整体后移。即如果array[j]的前一个数据array[j-1] > array[j], 那么就将array[j-1]和array[j]交换,然后j--, 直至array[j-1] <= array[j], 从而实现将数据插入效果

void insertSortC(int *array, int len)
{
if (array == nullptr || len < 0)
{
return;
}
for (int curr = 1; curr < len; ++curr)
{
for (int before = curr -1; before >=0 && array[before] > array[curr]; before--)
{
swap(before, before + 1);
}
}
}

void swap(int &a, int &b)
{
int tmp = a;
a = b;
b = tmp;
}


参考链接: http://blog.csdn.net/morewindows/article/details/6665714
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: