代码实现:
#include<iostream>
using namespace std;
void print(int a[],int n) {
for (int i = 0; i < n; i++) {
printf("%d ", a[i]);
}
printf("\n");
}
void Insertion_sort(int a[],int n) {
for (int i = 1; i < n; i++) {
int key = a[i];
int j = i - 1;
while (j >= 0 && a[j] > key) {
a[j + 1] = a[j];
j--;
}
a[j + 1] = key;
}
}
int main() {
int a[] = { 10,4,7,1,3,8 };
print(a, 6);
Insertion_sort(a, 6);
print(a, 6);
return 0;
}
练习:
说明插入排序算法在数组A={ 31 , 41 , 59 , 26 , 41 , 58 }的执行过程
初始数组:
因为是插入排序,可以想象成抓扑克牌:
我们手里的扑克牌是有序的,那么我们再抓一张牌,我们需要挑选一个合适的位置将其插入,并保持有序
比如一开始我们手中的牌是31,41,59.我们抓到一张牌是26,那么我们便希望将26插到31前面,形成26,31,41,59
这个排序的基本操作就是移动数组元素。
因为先抓一张牌,这张牌是 31 ,就一个数,不用排序,所以外层循环的 i 从1开始:
for (int i = 1; i < n; i++) {
第一次循环:
抓第二张牌,第二张牌是 41 ,将 41 与 31 进行比较,41 比 31 大,放在 31 的右边
i=1
key=a[i]=a[1]
for (int i = 1; i < n; i++) {
int key = a[i]; //保存的是抓到的牌的数
int j = i - 1;
while (j >= 0 && a[j] > key) {
a[j + 1] = a[j];
j--;
}
a[j + 1] = key;
}
抓到的牌是41,所以要将41与前面的数进行比较
41所在的数组下标是1,前面的数的数组下标就是0
第二次循环我们要比较的数就是59,数组下标是2,那么要比较的数的数组下标就是1,0
所以这就是为什么 int j = i - 1
然后就是内层的 while 循环这里有两个判断条件,一个是 j >= 0,另外一个是 a[ j ] > key
j >= 0 是 与循环体内部的 j -- 相对应,实现遍历
a [ j ] > key 可以自己手动多进行几次遍历就可以理解:
因为前三个数已经是升序了,所以咱们手动进行第第三次循环:
这是初始的情况:
j = 2;
key = a[3]=26;
然后while循环判断:while (j >= 0 && a[j] > key) ,显然满足
然后 a[j + 1] = a[j];
j--;
a[j + 1] = a[j]; 造成橙色框里的结果
j--; 使 j 向前移,j变成了1
然后重复:
退出循环时, j = -1;
最后是a[j + 1] = key;
也就是 a [0]= 26;
实际上while循环操作就是移动数组元素,给我们新插入的数留出一个合适的位置