插入排序的在生活中应用还是比较多的,相信大家都玩过扑克牌,每拿到一张牌时,我们都会进行的一个流程就是,将此张牌的面值与手中已有牌的面值进行比较,然后将这张牌插入到合适的位置。大脑进行的这个判断过程就是插入排序的过程。
假设上面就是我们手里已有的扑克牌,这时我们又拿到一张面值为“9”的扑克牌,我们就会进行如下的操作:
①将面值为“9”的扑克牌和面值为“K"的扑克牌进行数值大小比较,发现9<K,则暂时将9插入到K之前
② 将面值为“9”的扑克牌和面值为”Q"的扑克牌进行数值大小比较,发现9<Q,则暂时将9调整到Q之前
③将面值为“9”的扑克牌和面值为”J"的扑克牌进行数值大小比较,发现9<J,则暂时将9调整到J之前
④将面值为“9”的扑克牌和面值为”10"的扑克牌进行数值大小比较,发现9<10,则将9调整到10之前
至此我们就完成了一次插入排序,最终得到
当然实际生活中我们并不会傻傻的按步骤一步一步地执行上面的操作,我们通常将牌面值看一眼就会为它找到合适的位置,这就是人脑的聪明之处。
下面我们来看一看第一种插入排序算法的思路
先给出程序
#include<iostream>
using namespace std;
int main()
{
int a[] = { 13,4,25,11,56,6 };
cout << "before sort: ";
for (auto c : a)
{
cout << c << " ";
}
cout << endl;
int temp, i, j;
int n = sizeof(a)/sizeof(a[0]);
for (i = 1; i < n; ++i)
{
//数组的下标是从0开始的,这里从第二个数开始枚举
//即假定第一个数是有序的
temp = a[i]; j = i;
while (j >= 1 && temp < a[j - 1])
{
a[j] = a[j - 1];
j--;
}
a[j] = temp;
}
cout << "after sort: ";
for (auto c : a)
{
cout << c << " ";
}
cout << endl;
return 0;
}
算法运行结果如下
现在对该程序的执行流程进行模拟
元素值 | 13 | 4 | 25 | 11 | 56 | 6 |
位置下标 | 〇 | ① | ② | ③ | ④ | ⑤ |
令数组下标i从0开始,假定第一个数a[0]=13是有序的,然后从第二个数i=1从后往前遍历,遍历的过程就是为把当前遍历到的数插入到合适的位置。定义一个新变量j来辅助判断,每一次循环j=i;
i=1时,temp=4
13 | 4 | 25 | 11 | 56 | 6 |
j-1 | j |
用变量temp临时存放每一次需要排序的元素,每一次判断条件就是看temp与前一个元素a[j-1]的大小关系(假设需要从小到大排列元素),此时13>temp=4,需要交换两者的顺序,此时令 a[j] = a[j - 1], 即让原来的 j - 1项往后移一位,然后 j-- 让 j 继续枚举前面的数;
13 | 13 | 25 | 11 | 56 | 6 |
j |
但是j已经到达数组的最前端,而且temp已经无法满足小于a[j-1],所以这时跳出循环,并将temp的值赋给a[j];
4 | 13 | 25 | 11 | 56 | 6 |
j |
至此,第一轮排序完成
i=2时,temp=25
4 | 13 | 25 | 11 | 56 | 6 |
j-1 | j |
a[j-1]<temp,两者不用交换顺序;这一轮排序完成。
i=3时,temp=11
4 | 13 | 25 | 11 | 56 | 6 |
j-1 | j |
a[j-1]>temp,将a[j-1]赋给a[j],
4 | 13 | 25 | 25 | 56 | 6 |
j-1 | j |
j--;
4 | 13 | 25 | 25 | 56 | 6 |
j-1 | j |
a[j-1]>temp,将a[j-1]赋给a[j],
4 | 13 | 13 | 25 | 56 | 6 |
j-1 | j |
j--;
4 | 13 | 13 | 25 | 56 | 6 |
j-1 | j |
a[j-1]<temp,将temp赋给a[j]
4 | 11 | 13 | 25 | 56 | 6 |
j-1 | j |
i=4时,temp=56
4 | 11 | 13 | 25 | 56 | 6 |
j-1 | j |
a[j-1] <temp,不需用交换两者元素,进行下一趟排序
i=5时,temp=6
4 | 11 | 13 | 25 | 56 | 6 |
j-1 | j |
a[j-1]>temp,将a[j-1]的值赋给a[j]
4 | 11 | 13 | 25 | 56 | 56 |
j-1 | j |
j--;
4 | 11 | 13 | 25 | 56 | 56 |
j-1 | j |
a[j-1]>temp,将a[j-1]的值赋给a[j]
4 | 11 | 13 | 25 | 25 | 56 |
j-1 | j |
j--;
4 | 11 | 13 | 25 | 25 | 56 |
j-1 | j |
a[j-1]>temp, 将a[j-1]的值赋给a[j]
4 | 11 | 13 | 13 | 25 | 56 |
j-1 | j |
j--;
4 | 11 | 13 | 13 | 25 | 56 |
j-1 | j |
a[j-1]>temp,将a[j-1]的值赋给a[j]
4 | 11 | 11 | 13 | 25 | 56 |
j-1 | j |
j--;
4 | 11 | 11 | 13 | 25 | 56 |
j-1 | j |
a[j-1]<temp,将temp的值赋给a[j]
4 | 6 | 11 | 13 | 25 | 56 |
j-1 | j |
好了,到此为止我们已经完成了排序。
那么还可以用另外一种方式实现插入排序
#include<iostream>
using namespace std;
int main()
{
int arr[] = { 13,4,25,11,56,6 };
int len = sizeof(arr) / sizeof(arr[0]);
cout << "before sort: ";
for (auto c : arr)
{
cout << c << " ";
}
cout << endl;
for (int i = 1; i < len; ++i)
{
for (int j = i; j > 0; j--)
{
if (arr[j - 1] > arr[j])
{
int temp = arr[j-1];
arr[j - 1] = arr[j];
arr[j] = temp;
}
}
}
cout << "after sort: ";
for (auto c : arr)
{
cout << c << " ";
}
cout << endl;
return 0;
}
运行结果如下: