排序算法汇总——冒泡排序
排序算法汇总(小→大)
冒泡排序
助记方法:排序如其名,小的气泡要到前面,但是气泡不是一下子升到前面而是两两比较
流程:从第一个数开始两两比较,发现前面的比后面大,就交换两者,第一轮从头到尾遍历之后,整个数组的最大的元素就会到最后面;
然后忽略掉最后面已经确定位置的数,前面的数再次两两比较,这样又能确定倒数第二个大的数值;
代码:
public static void bubble(int n,int[] arr)
{
for(int j=0;j<n;j++)//第一层是冒泡排序要比较的轮数
{
for(int i=0;i<n-1-j;i++)//第二层是冒泡排序要比较的数字个数
{
int temp=0;
if(arr[i]>arr[i+1])
{
temp=arr[i+1];
arr[i+1]=arr[i];
arr[i]=temp;
}
}
}
}
代码解释:
对于第一层的循环中,因为在最后比较完成后,第一位的数自动确定,这样就不用再去进行新一轮的比较,所以轮数为(n-1)
对于第二层的循环中,因为从是前一个数和后一个数的比较,这里就涉及到了[i+1]的问题,数组中这种总会出现数组越界的错误;
这里在第二版中会进行改正;在这里,我们每一轮要比较的i值为数字的每次参与比较的数字-1,也就是红色框中的数字:
第二版代码:
public static void bubble(int n,int[] arr)
{
for(int j=0;j<arr.length;j++)
{
for(int i=1;i<arr.length-j;i++)
{
int temp=0;
if(arr[i-1]>arr[i])
{
temp=arr[i];
arr[i]=arr[i-1];
arr[i-1]=temp;
}
}
}
}
代码解释:
优化后的代码直接用.length获取数组的长度,而不是传参的方式
从i=1号位开始比较的话,(arr[i-1]>arr[i])就避免了数组的越界问题
优化冒泡排序1:
当给定的序列已经是排序完成或者在某轮交换的途中就已经完成,此时可以作为优化的地方,跳出排序
public static void bubble(int n,int[] arr)
{
for(int j=0;j<arr.length;j++)
{
boolean flag=true;
for(int i=1;i<arr.length-j;i++)
{
int temp=0;
if(arr[i-1]>arr[i])
{
temp=arr[i];
arr[i]=arr[i-1];
arr[i-1]=temp;
flag=false;//只要进入到了交换中,就不是已经排列好的结果
}
}
if(flag)//只要发现某一轮没有进入到交换中,本轮就已经完成了排序,跳出循环
break;
}
}
但是对于一般的情况很少出现大数据中几轮就会有排好序的情况,所以可能优化后的运行时间还不如优化前的时间!!!