冒泡排序的个人理解
去新松面试笔试题中最后一道是冒泡排序,看到这题先是兴奋后是悲哀。
兴奋的是这么简单啊,上大学时整的老明白了,考试的时候也为数不多的自己答的题。
悲哀的是毕业后就再也没用过,全都就饭吃了。。。
想想看我最有文化的时候应该就是高三了,但是当年的数理化知识现在还记得多少?
花了一个小时恶补了一下,唉!这学习能力赶上老年人了。
下面说正事,区区几行代码信息量还不少。
int a[10] = {9,8,7,6,5,4,3,2,1,0};
bool bIsSwap = true;//判断后面的序列是否已经有序
for (int i=0;i<10-1 && bIsSwap;i++)
{
bIsSwap = false;//如果在第二个循环中一次也没有进行交换则数组中i后面的已经是有序的了不需要再运行。
for (int j=10-1;j>i;j--)//如果i=0,j=9第二个循环就会比较9次,就是说j的循环次数始终是数组中剩下的无序数的数量减1。
{
if (a[j-1] > a[j])//如果前一个数比后一个大则交换数据,也就是冒了一次泡。
{
int iData = a[j];
a[j] = a[j-1];
a[j-1] = iData;
bIsSwap = true;
}
}
}
这里i只起到控制循环的作用,并没有用来操作数组。外面的循环每运行一次都会从数组中剩下的没排好序的序列中找出一个最小值。
比如第一次循环一定能找出数组中最小值,第二次循环一定能找出数组中第二小的值如此反复。
所以i可以被当作一个flag,标记当前正在查找数组中第几小的数,里面的循环中j>i就起这个作用。
因为有数组中有10个数,这样外面的循环只需要循环9次就能找出数组中最小的9个数并排好序。
在里面的循环中,每次j都从数组的最后端向前端查找,在查找的过程中会“顺带”的把数组中剩下的较小的值向上提升,这就比j从大到小查找更有效率。
我这个例子比较极端是完全逆序的数组,如果不是完全逆序就更容易看出。
比如int a[10] = {9,0,8,7,6,2,5,4,3,1};
第一次循环时会把1"提升"到现在的9后面,数组变成 {0,9,1,8,7,6,2,5,4,3}如果第二个循环写成for (j=i+1;j<=10;j++)
则外面的循环在第二次循环时会将2换到现在1的位置,也就是数组的最后,数组变成{0,1,9,8,7,6,5,4,3,2},这样就增加了比较次数。