冒泡排序:(升序为例)
利用两个for循环每次比较相邻的两个元素,如果前一个元素比后一个元素大则交换两个数。外层的for循环控制排序的总趟数,内层的for循环控制每一趟的相邻两个数的比较的次数
我们很轻易的看出:
冒泡排序的时间复杂度最好情况为:
冒泡排序的时间负责督最坏情况为:
冒泡排序是稳定的排序
一.
下边我们以数组array[ ] = {5,8,6,3,9,2,1,7}为例,做升序排序
第一趟: 5 --> 8 --> 6 --> 3 --> 9 --> 2 --> 1 --> 7
5 --> 6 --> 8 --> 3 --> 9 --> 2 --> 1 --> 7
5 --> 6 --> 3 --> 8 --> 9 --> 2 --> 1 --> 7
5 --> 6 --> 3 --> 8--> 2 --> 9 --> 1 --> 7
5 --> 6 --> 3 --> 8 --> 2 --> 1 --> 9 --> 7
5 --> 6 --> 3 --> 8 --> 2 --> 1 --> 7 --> 9
第二躺: 5 --> 3 --> 6 --> 8 --> 2 --> 1 --> 7 --> 9
5 --> 3 --> 6 --> 2 --> 8 --> 1 --> 7 --> 9
5 --> 3 --> 6 --> 2 --> 1 --> 8 --> 7 --> 9
5 --> 3 --> 6 --> 2 --> 1 --> 7 --> 8 --> 9
第三趟:
第四趟:
第五趟:
第六趟: 1 --> 2 --> 3 --> 5 --> 6 --> 7 --> 8 --> 9
第七躺:
第八躺:
由于太多了,只能写出少部分,和特殊的,其中没写的都是重复以上动作
代码展示:
void BubbleSort(int array[],int sz)
{
for (int i = 0; i < sz; i++)
{
for (int j = 0; j < sz - i - 1 ; j++)
{
if (array[j] > array[j + 1])
{
int temp = 0;
temp = array[j + 1];
array[j + 1] = array[j];
array[j] = temp;
isSoretd = false;
}
}
}
}
二.
我们可以看出,当我们不假思索的写出以上代码时,这个大部分人都可以搞定,这时候面试官肯定会问我们该去优化他
使得他效率更高。
我们可以看到上面演示的过程中,在第六趟的时候,这个数组里的数据已经是有序的了,然而我们还多余的跑了两趟,大大的降低了代码的效率。
解决方法:
我们可以利用特殊的函数来标记当数据已经是有序的就可以跳出循环。这时候我们就可以利用boolean(布尔变量)isSorted作为标记。如果在本轮排序中没有元素交换就证明数据已经有序,直接跳出循环。
布尔变量:
是由两种逻辑状态的变量,他们分别为:true 和 false 常被用来作为标记
代码展示:
void BubbleSort(int array[],int sz)
{
for (int i = 0; i < sz; i++)
{
boolean isSoretd = true;
for (int j = 0; j < sz - i - 1 ; j++)
{
if (array[j] > array[j + 1])
{
int temp = 0;
temp = array[j + 1];
array[j + 1] = array[j];
array[j] = temp;
isSoretd = false;
}
}
if (isSoretd)
{
break;
}
}
}
三.
这时候我们可以看到,代码在面对一些特殊情况时,效率上已经得到了极大的提升,但是这时候面试官可能觉得还不够,我们还必须去进一步优化。
来看以下情况:(升序)
我们选定一个新的数组 array[ ] ={3,4,2,1,5,6,7,8};
我们可以可到这个数组内前半部分是无序的(3,4,2,1)但是后边确实升序(5,6,7,8)
让我们来看一下按照以前的方法排序过程:
第一趟:3 --> 4 --> 2 --> 1 --> 5 --> 6 --> 7 --> 8
3 --> 2 --> 4 --> 1 --> 5 --> 6 --> 7 --> 8
3 --> 2 --> 1 --> 4 --> 5 --> 6 --> 7 --> 8
。。。。。。。。
第二趟:2 --> 3 --> 1 --> 4 --> 5 --> 6 --> 7 --> 8
2 --> 1 --> 3 --> 4 --> 5 --> 6 --> 7 --> 8
第三趟:1 --> 2 --> 3 --> 4 --> 5 --> 6 --> 7 --> 8
从上边的过程我们可以看出,每趟的排序中在后边是已经有序的数据,但是在每一轮的排序中还会去做无用功,这又一次大大的降低了程序运行的效率。
我们可以看到影响效率的问题关键是:对数列有序区的界定
为了解决这个问题我们可以在没一轮的循环中,记录数据最后一次交换的位置,则这个就是数列的有序的边界
代码展示:
void BubbleSort(int array[],int sz)
{
//排序的最新边界
int sortborder = sz - 1;
//记录最后一次交换的位置
int lastchange = 0;
for (int i = 0; i < sz; i++)
{
boolean isSoretd = true;
for (int j = 0; j < sortborder; j++)
{
if (array[j] > array[j + 1])
{
int temp = 0;
temp = array[j + 1];
array[j + 1] = array[j];
array[j] = temp;
isSoretd = false;
lastchange = j;
}
}
sortborder = lastchange;
if (isSoretd)
{
break;
}
}
}
以上就是本人自己想到的优化的地方,如果大家有什么可以进一步优化的地方麻烦留言告诉我一声,大家互相进步。