今天数据结构开课啦,第一节冒泡排序
1、解说:冒泡,顾名思义是小的数字往上冒,此处我们可以理解有一个数组,最终要求的结果是数组的排序顺序是从小到大,可以形象的认为,每个数字是一个气泡,当后面的数字小的时候,就往上冒。我们从数组的最后的位置开始两两比较 (index) 和 (index-1) 两个位置的数据,如果 (index-1) 大于 (index)则二者交换位置,交换之后,index-1 再跟前面的比,直到排序结束;
举例,如果有一组数是【1,5,8,7,4】
第一趟
i
j-1 j
1 5 8 7 4
j-1 j
1 5 8 4 7
j-1 j
1 5 4 8 7
j-1 j
1 4 5 8 7
1 4 5 8 7
第二趟
i
j-1 j
1 4 5 8 7
j-1 j
1 4 5 7 8
………………
从上例可以看出正确排序已经出现,但是实际上代码还在运行,直至所有的循环走完
**********华丽的分割线************
2、代码:(冒泡排序可实现的代码有很多种,下面是其中一种)
public class BubbleSort {
public static void main(String[] args) {
int[] a = { 1, 5, 8, 7, 4 };
int temp = 0;
for (int i = 0; i < a.length; i++){
for (int j = a.length - 1; j > 0; j--){
if (a[j - 1] > a[j]){
temp = a[j];
a[j] = a[j - 1];
a[j - 1] = temp;
}
}
}
}
}
3、是否是稳定算法:是
冒泡排序就是把小的元素往前调或者把大的元素往后调。比较是相邻的两个元素比较,交换也发生在这两个元素之间。所以,如果两个元素相等,我想你是不会再无聊地把他们俩交换一下的;如果两个相等的元素没有相邻,那么即使通过前面的两两交换把两个相邻起来,这时候也不会交换,所以相同元素的前后顺序并没有改变,所以冒泡排序是一种稳定排序算法。
4、复杂度:
若文件的初始状态是正序的,一趟扫描即可完成排序。所需的关键字比较次数C和记录移动次数M均达到最小值:Cmin=n-1,Mmin=0。冒泡排序最好的时间复杂度为O(n)。
若初始文件是反序的,需要进行n-1趟排序。每趟排序要进行n-i次关键字的比较(1≤i≤n-1),且每次比较都必须移动记录三次来达到交换记录位置。在这种情况下,比较和移动次数均达到最大值:Cmax=n(n-1)Π2=O(n²),Mmax=3n(n-1)Π2=O(n²)。冒泡排序最坏情况的时间复杂度是O(n²)
算法的平均时间复杂度为O(n²)。虽然冒泡排序不一定要进行n-1趟,但由于它的记录移动次数较多,故平均时间性能比直接插入排序要差得多。
5、优化:
上面我们已经看到,当正确的排序已经出现的时候,循环依然在继续,直到完成,这也太浪费资源了,我们可以设置一个标识符。
public class BubbleSort {
public static void main(String[] args) {
boolean k = true;
int[] a = { 1, 5, 8, 7, 4 };
// int[] a = { 1, 2, 3, 4, 5 };
int temp = 0;
for (int i = 0; i < a.length && k; i++) {
k = false;//只要flag在下一次外循环条件检测的时候值为false,就说明已经排好序,不用继续循环
for (int j = a.length - 1; j > 0; j--) {
if (a[j - 1] > a[j]) {
temp = a[j];
a[j] = a[j - 1];
a[j - 1] = temp;
k = true;// 如果有交换,就将标记变量赋true
}
System.out.println(i);// sysout,然后快捷键Alt+/
}
}
}
}