现实中的排序不出不在,比如说高校之间的比较,根据某一特定的指标进行排序;比如说,学生的成绩排名;比如说在网上进行购物时我们可以根据购物量或者好评率或者评论数等等进行排序。
排序的概念:
所谓排序,就是使一串记录,按照其中的某个或某些关键字的大小,递增或递减的排列起来的操作。
排序的分类:
排序又分为内部排序
和外部排序
。
内排序: 数据元素全部放在内存中的排序。
外排序: 数据元素太多不能同时放在内存中,根据排序过程的要求不能在内外存之间移动数据的排序。
我们在玩扑克牌时,就利用了直接插入排序的思想, 把待排序的记录按其关键码值的大小逐个插入到一个已经排好序的有序序列中,直到所有的记录插入完为止,得到一个新的有序序列 。
排序的思想结合这个扑克牌的例子,插入排序,简单理解,就是,对于原来一个已经排好序的有序数组,然后逐个
插入,插入一个,排一次序,使得这个新插入的数被放在一个合适的位置,再次插入后的使得新的数组是有序的,再插入一个,则再次排序…依次循环,直至插入停止。
首先,我们一定要明白和理解单趟排序,即对于一个有序的数组插入一个数。
给定一个有序数组,将要插入的数放在有序数组的最后,例如:
然后我们进行插入排序:
首先设置end,使得指针指向原有数组的最后一个位置,然后将我们要插入的数6和end所指的数9进行比较。
6<9,则需要将9其后的位置赋值为9,同时将end向前移动。
然后我们紧接着,让我们要插入的元素即6和end所指的当前的元素7进行比较。
6<7,则我们将7后面的位置赋值为7,(也就将原来的9覆盖掉了),然后end–,使得end指向前一个元素。
接着,我们让我们要插入的元素和end当前所指的元素进行比较。
6>5,即我们要插入的元素6大于end当前所指的元素5,这时,循环停止,我们将我们要插入的元素6插入到end当前所指元素即5的下一个位置即可。这样,我们的一趟插入排序就完成了。
下面程序是单趟循环,[0,end]有序,把end+1位置的元素插入前序序列,使得控制最后[0,end+1]有序。
void InsertSort1(int* a,int n)
{
int end=n-1;
//将要插入的元素定义为放在原数组的最后一个元素
int tmp=a[end+1];//用变量tmp来保存新插入的元素,防止被覆盖掉
while(end>=0) //与新插入的元素相进行比较的元素,下标一定≥0
{
if(tmp<a[end])
{
//挪动 (也就是赋值)
a[end+1]=a[end];
}
else //大于等于 则插入到end的后面一个空
{
break; //插入完成,退出循环
}
end--;//更新end 使得循环继续
}
a[end+1]=tmp;
}
单趟变整体,已经排好序的数组中最开始只有一个元素,即a[0],然后插入第二个元素a[1],进行排序,然后插入第三个元素a[3]进行排序…直到插入最后一个元素a[n-1]进行排序。
则算法:
void InsertSort(int*a,int n)
{
int i;
for(i=1;i<n;i++)
{
int end=i-1;
int tmp=a[i];
while(end>=0)
{
if(tmp<a[end])
{
a[end+1]=a[end];
}
else
{
break;
}
end--;
}
a[end+1]=tmp;
}
}
我们放在主函数进行测试运行:
int main()
{
int a[5] = { 1,10,20,4,8 };
InsertSort(a, 5);
int i;
for (i = 0; i < 5; i++)
{
printf("%d ", a[i]);
}
return 0;
}