一、插入排序:
插入排序也可以叫直接插入排序,就和我们打扑克牌类似,发下来的牌是无序的,但是我们会将它抽出来 插到 对应位置,插完后,就可以得到一副有序的牌,对手出牌,我们可以根据直观的看清自己能否吃掉对手!!
二、思路:
1、从第1个元素开始,可以认为该元素已经排好序了
2、抽出后一个元素tmp,和其前面的元素一一比较
3、若是该元素 比 抽出的元素 大(或者小——要根据你是要升序还是要降序来确定,我们这里以升序为主),就要将该元素挪动到后一个位置(也就是后挪一位)
4、tmp不断向前和各个元素比较,重复3操作。当有一个元素比tmp小时,插到其后面的位置(若是前面的元素没有比抽出的元素小的情况(其前面所有元素都比这个抽出来的元素大的话),将元素插入下标为0的位置)此时从刚开始时tmp的下标到下标为0的位置已经有序
5、重复2-4操作,直到抽出的tmp为最后一个元素,也就是全部排好了
静态的图:以一趟为例,其实底层逻辑是将tmp取出,然后让前一个元素去覆盖后一个,由于tmp保存了该元素,防止了该元素的丢失
三、时间复杂度:
时间复杂度:一组逆序的数就是最坏的情况:O(N^2)
最好的情况:一组有序的数,遍历一遍就可以 O(N);
四、代码实现:
先写底层逻辑,也就是进行交换的那一层,最开始从0开始的,最后下标为啥不是end呢??因为我们后挪一次,end就会减一次,所以我们放入的是end要加1,你想想下标为0的元素移动到下标为1,end-1 == -1,下标可没有小于0的说法
下面我们来实现整体代码,发现了么end=0换成了end=i,然后套一个循环控制趟数,i表示的是第几趟数(也就是从那个下标开始);这里为啥最后小于n-1??因为tmp存的是end+1的值,你要是i<n,不就越界访问了么!!注意下,当然代码写法每个人风格不一样,根据自己风格来就行
//插入排序:end+1前面的是有序的,不断拿end+1去比较
void InsertSort(int* a, int n)
{
int i;
for (i = 0; i < n - 1; i++)
{
int end = i;
int tmp = a[end + 1];
while (end >= 0)
{
if (a[end] > tmp)
{
a[end + 1] = a[end];
end--;
}
else
{
break;
}
}
a[end + 1] = tmp;
}
}
提示:真的最好先写一次 然后再写整体;清晰的逻辑写代码真的很舒服
感 谢 观 看