插入排序应该算是比较好理解的一种了,原理类似于我们打牌的时候,摸牌插入手中的情景。来看一下图,立刻就明白了:
我们将一个数组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; } } }
时间: 2024-11-25 17:55:11