首页 > 代码库 > 算法入门之二(插入排序)

算法入门之二(插入排序)

插入排序应该算是比较好理解的一种了,原理类似于我们打牌的时候,摸牌插入手中的情景。来看一下图,立刻就明白了:


我们将一个数组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;
		}
	}

}




算法入门之二(插入排序)