目录
而i时:系统崩溃,数组越界!!!<>小于n时:
此种排序思路核心:
当插入第i(i>=1)个元素时,前面的array[0],array[1],…,array[i-1]已经排好序,此时用array[i]的排序码与 array[i-1],array[i-2],…的排序码顺序进行比较,找到插入位置即将array[i]插入,原来位置上的元素顺序后移。
举个例子:
在我们玩斗地主的时候,我们都会摸17张牌,每次摸到手里的牌都会进行从小到大的顺序进行排列,比如已经摸到3,7,10,K了,再摸到第五张牌——黑桃8时,我们会进行比较:8遇到K,8小往左看;8比较10,8小,继续往左看,8比较7,8大,于是就将牌8插入到7的后面即可。注意:前4张牌的顺序一定是从小到大的有序排列牌。
时间复杂度:
直接插入排序时,最好的情况为:O(N)——即插入的所有数据都是依次递增的顺序(升序),这样就不需要挪动顺序,直接一个个的放入数据即可。
最坏的情况为:O(N * N)——即插入的所有数据都是依次递减的顺序(降序),插入第二个数据时,要挪动一次,插入第三个数据时,要挪动两次...... 所以插入n个数据要挪动N次。
直接插入排序动态图:
函数实现代码:
//插入排序
void InsertSort(int* arr, int n) {
for (int i = 0; i < n-1; i++) {
int end = i;
int tmp = arr[end + 1]; //tmp是要插入的一个数据
while (end >= 0) {
if (arr[end] > tmp) { //tmp若是小于要比较的对象值,就让arr[end]往后移,
//end--,这样就能腾出位置,直到arr[end]<tmp,
//tmp就可以
arr[end + 1] = arr[end];
--end;
}
else {
break;
}
}
arr[end + 1] = tmp; //先排序,找位置,位置找好后,就可以放数据了
}
}
注:for循环中,i的范围一定是i<n-1,i<n是错的会造成系统崩溃,end的最终位置一定处在数组的第n-2处 因为end是下标从0开始,且实参传的是arr的首元素地址,那么数组的第一个元素会在函数接收的时候就已经传进去了,所以tmp的值是直接从数组的第二个元素开始比较,而且需要给arr[end+1]腾位置,以免arr[end+1]造成数组越界。
测试:
void TestInsertSort() {
int arr[] = { 34,56,25,65,86,99,72,66 };
int size = sizeof(arr) / sizeof(arr[0]);
InsertSort(arr,size );
for (int i = 0; i < size; i++) {
printf("%d ", arr[i]);
}
printf("\n");
}
int main() {
TestInsertSort();
return 0;
}