插入排序应该算是比较好理解的一种了,原理类似于我们打牌的时候,摸牌插入手中的情景。来看一下图,立刻就明白了:
我们将一个数组int a[12] 看做一副扑克牌,假设数组有12个数,那么扑克牌也一共有十二张,放在一起开始;
我们先抽一张拿到手上,这时候,我们不需要排序,因为不论哪一张先被我们抽上来,不论大小都只有一张,我们不妨将这张牌定为a[0]
然后我们再抽一张(a[1]),假设我们打牌的习惯是牌抽上来的牌从小到大排列,左边的牌最小,右边的牌最大(即数组从小到大排序),那我们我们抽上来的第二张牌,先要跟抽上来的第一张牌(已经拿在手上的这张)进行大小比较,如果小于第一张牌(a[0]),那么就应该放在a[0]的左边;如果大于第一张牌(a[0]),那么就应该放在a[0]右边;如果两张牌相等,怎么放都行。
然后我们再抽第三张牌(a[2]),这时我们就需要遍历一下手上已经拿到且排好序的两张牌,看看有没有一张牌比a[2]大,如果有,a[2]就要插入到这个比它大的位置,如果没有,那么a[2]就放在最右边即可;如果要插入,在插入之前,要把后面的牌依次先往后移动一位,给a[2]腾出一个位子,这样a[2]再插入其中。
之后每摸一张牌,都需要进行一次这样的遍历,将摸到的新牌插入到最合适的位置,直到最后一张牌插入完毕,手上的牌也就按从小到大的顺序排列好了,相应的我们的数组也就已经排序完毕。
按照这样的思想,我们能比较容易的写出插入排序的代码:
#include <iostream>
//数组长度
#define MAX_SIZE 12
//数组最大下标
#define MAX_INDEX MAX_SIZE-1
typedef int T;
using namespace std;
//申明插入排序函数
void insertSort(T* a);
//申明打印数组的函数
void printArr(T a[]);
int main() {
//待排序的数组
int a[MAX_SIZE] = { 8, 5, -1, 99, 14, 17, 14, 63, 14, 75, -1023, 0 };
printArr(a);
insertSort(a);
printArr(a);
return 0;
}
/*
* 打印数组函数
*/
void printArr(T a[]) {
for (int i = 0; i < MAX_SIZE; i++) {
cout << a[i] << ' ';
}
cout << endl;
}
/*
* 插入排序函数
*/
void insertSort(T* a) {
int i, j, k, tmp;
//外圈的循环,每一次循环都是新抽出的一张牌,所以从1开始到MAX_INDEX结束,因为最开始0那一张牌应该是拿在手上的
for (i = 1; i <= MAX_INDEX; i++) {
for (j = 0; j < i; j++) {//已经到手的牌的遍历过程,找到需要的位置
//从小到大排序
if (a[j] > a[i]) {
break;
}
}
//拿到的这个a[j],是序列里面第一个大于a[i]的数,也可能不存在,那么这时j应该==i
if (j < i) {
//先临时保存a[i],以免被移动复制的时候覆盖掉值
tmp = a[i];
//做依次后移工作,应该是要从j到i-1都要依次后移一位
for (k = i - 1; k >= j; k--) {
a[k + 1] = a[k];
}
//真正将a[i]的原值插入j位置
a[j] = tmp;
}
}
}
原文地址:http://blog.csdn.net/cyp331203/article/details/41620475