最近在学数据结构与算法设计,里面插入排序让我想了一下
算法思想:(假设排成递增序列)
一开始把第一个元素看作有序的,然后从这个元素的后一个元素开始依次往前比较,遇到了比它大的则交换,直到遇到了比它小的或者已经移动到了整个序列的第一个位置为止。
代码如下
void inssort(int arr[],int n)
{
for(int i=1;i<n;i++)
{
for(int j=i;j>0&&arr[j-1]>arr[j];j--)
{
swap(arr[j],arr[j-1];
}
}
}
其实整个算法思想和代码都很好懂,然后我想着能不能改一下,让i=0开始呢。现在i=1说明前面下标为0~i-1的元素都已经是有序的了,下标为i的正是我们要插入的元素。
一开始我觉得只需要简单的修改一下,i=0,然后j=i+1即可,但是我发现了一点小问题。
i=n-1的时候,按照我们的思路,就是说其实整个序列都已经有序了,已经无需再排列了。而且有一个数组下标溢出的问题,因为arr[j]即arr[i+1]即arr[n]是超出了我们传入的数组的大小的。
解决的方法可以在内部循环里面加一个判断语句,判断j=i+1是不是小于n,但其实这也是有风险的在我看来。
更加保险的改法是在外部循环,i<n改为i<n-1即可
这个小思考我觉得挺有趣的,就是把一些算法改一下我们会发现,其实前人已经考虑很多了,我们如果要改变的话其实不仅要考虑整个算法在思路和具体实现上可不可行,还特别需要考虑一些边界情况。在这里选择排序还算是好分析,因为其实代码实现不困难,但是在后面的一些经典排序算法则会有所难度了。