直接插入排序:一开始将数据分为两部分,初始数据当做无序,每一次从待排序队列中取出一个值,放到我们已经排序好的队列中,然后将其调整有序,然后再从待排序队列中取一个值,直到待排序队列中没有值,再结束。
调整规则:将待插入的值和有序队列中的所有值挨个比较(从右向左),找到一个小于或者等于自己的值,则停下来,插入到当前位置的下一个位置。要么触底要么找到合适的位置
直接插入排序的特点:1.时间复杂度过大O(n^2)合适的使用场景:n比较小的时候
2.数据越有序,则直接插入排序的效率越高
这幅图对应方法1:其中i代表的是趟数,j代表这一趟开始的时候已排序队列中的最后一个值的下标,从图中可以很容易看出每一次j 都是与 i 相差1的,所以他们的关系式为:j = i -1 ;
代码实现(方法一):
#include<stdio.h>
#include<stdlib.h>
#include<vld.h>
#include<assert.h>
/*
稳定性:如果排序之前 3在3'的前面 但是排序后 3跑到了3'的后面 则认为他不稳定
1.直接插入排序:每一次从待排序队列中去一个值放到已排序队列中,然后调整有序,然后再取在排序,直到待排队列没有值
*/
//直接插入排序 时间复杂度O(n^2) 空间复杂度O(1) 稳定性:稳定的
void InsertSort(int* arr, int len)
{
//assert arr!=NULL;
for (int i = 1; i < len ;i++) //代表一共跑的趟数
{
int j;
int tmp = arr[i];//带插入的值
//j指向 这一趟开始的时候的已排序好的队列的最后一个值的下标
for (j = i - 1; j >= 0;j--)//这里控制待插入的值和已排序队列的挨着比较(从右往左排序)
{
if (arr[j] <= tmp)
{
break;//这时应该停下来
}
else
{
arr[j + 1] = arr[j];
}
}
arr[j + 1] = tmp;
}
}
void Show(int arr[], int len)
{
for (int i = 0; i < len; i++)
{
printf("%d ", arr[i]);
}
printf("\n");
}
int main()
{
int arr[] = { 12,2,39,88,4,6,25,232,62,221 };
InsertSort(arr, sizeof(arr) / sizeof(arr[0]));
Show(arr, sizeof(arr) / sizeof(arr[0]));
return 0;
}
调试结果为:
这幅图对应方法2:因为第一趟排序是可以省略的,而图中,每一次j 都是与 i 指在同一个位置的,所以在这幅图中i与j的关系为:j = i ;
代码实现(方法二):
#include<stdio.h>
#include<stdlib.h>
#include<vld.h>
#include<assert.h>
void InsertSort1(int* arr, int len)
{
//assert arr!=NULL;
for (int i = 0; i < len-1; i++) //代表一共跑的趟数
{
int j;
int tmp = arr[i+1];//带插入的值
//j指向 这一趟开始的时候的已排序好的队列的最后一个值的下标
for (j = i ; j >= 0; j--)//这里控制待插入的值和已排序队列的挨着比较(从右往左排序)
{
if (arr[j] <= tmp)
{
break;//这时应该停下来
}
else
{
arr[j + 1] = arr[j];
}
}
arr[j + 1] = tmp;
}
}
void Show(int arr[], int len)
{
for (int i = 0; i < len; i++)
{
printf("%d ", arr[i]);
}
printf("\n");
}
int main()
{
int arr[] = { 12,2,39,88,4,6,25,232,62,221 };
InsertSort1(arr, sizeof(arr) / sizeof(arr[0]));
Show(arr, sizeof(arr) / sizeof(arr[0]));
return 0;
}
调试结果为: