写了一个插入排序,结果就翻车了,搞不懂这两段为什么运行的结果不一样?
#include<stdio.h>
void print(int arr[], int n){
for(int i = 0; i < n; i++ ){
printf("%d ", arr[i]);
}
printf("\n");
}
// arr[i]和temp的值是相同的,但是运行的结果不同??
void insertSort(int arr[], int n){
for(int i = 1; i < n; i++ ){
// 该变量是用来保存被覆盖的元素
int temp = arr[i];
int j = i - 1;
while(j >= 0 && arr[i] < arr[j]){
arr[j + 1] = arr[j];
j--;
}
arr[j + 1] = temp;
}
}
void insertSort2(int arr[], int n){
for(int i = 1; i < n; i++ ){
int temp = arr[i];
int j = i - 1;
while(j >= 0 && temp < arr[j]){
arr[j + 1] = arr[j];
j--;
}
arr[j + 1] = temp;
}
}
int main(void){
int arr[] = {3, 2, 5, 8, 4, 7, 6};
insertSort(arr, 7);
print(arr, 7);
}
运行结果是:
这个是插入排序的优化写法,思路就是把他前面比他大的数字全都后移一位,直到有一个不比他小了这个位置就是他因该放置的位置,这种做法比两两交换数字至少要快上10%
首先我们可以根据while循环条件判断出几个变量的范围
j : [0,i-1]
j+1:[1,i]
temp: arr[i]
只要保持在while循环中保持上面的循环不变量不变那么这个循环就是正确的,但是不难看出在
insertSort
中第一轮循环时执行了语句arr[j + 1] = arr[j];
所以原本arr[i]的值就会被arr[i-1]覆盖掉(详情看上面的变量范围),而且循环的判断条件是基于arr[i]的,所以他的循环不变量发生了改变出来的结果会和预期不符,而把temp作为判断条件就不会出现这种情况,因为他一直存储者arr[i]的原始值