走进数据结构之排序(三)---冒泡排序

来源:互联网 发布:linux 安全扫描工具 编辑:程序博客网 时间:2024/05/22 02:13

一、冒泡排序算法分析

比较相邻两个元素大小,如果反序,则交换。若按升序排序,每趟将数据序列中的最大元素交换到最后位置,就像气泡从水里冒出一样。

二、代码实现

package top.einino.swapsort;

public class BubbleSort {

//交换keys[i]与keys[j]元素,i、j范围由调用者控制
private static void swap(int[] keys, int i, int j){
  int temp = keys[j];
  keys[j] = keys[i];
  keys[i] = temp;
}

//默认升序状态
public static void bubbleSort(int[] keys){
bubbleSort(keys, true);
}

//进行冒泡排序,asc为true表示升序,asc为false表示降序
private static void bubbleSort(int[] keys, boolean asc) {
System.out.println(“冒泡排序(”+(asc?”升”:”降”)+”序)”);
//是否交换的标记,如果在排序的进行过程中,没有交换了就可以退出循环,完成排序
boolean exchange = true;
//有交换时再进行下一趟,最多n-1趟
for(int i=1; i<keys.length && exchange; i++){
//开始排序前,将标记设置为false
exchange = false;
for(int j=0; j<keys.length-i; j++){
if(asc?keys[j]>keys[j+1]:keys[j]<keys[j+1]){
 swap(keys, j, j+1);
//交换过,更改交换的标志
  exchange = true;
}
}
System.out.println(“第”+i+”趟”);
print(keys);
}
}
//输出排序数组
private static void print(int[] keys) {
for(int key : keys){
System.out.print(key+” “);
}
System.out.println();
}

public static void main(String[] args) {
int[] keys = {32, 26, 87, 72, 26, 17};
int[] keysDesc = {32, 26, 87, 72, 26, 17};
//测冒泡升序排序
BubbleSort.bubbleSort(keys);
//测试冒泡降序排序
BubbleSort.bubbleSort(keysDesc, false);
}

}

三、形象的小例子

还是体育老师排队伍。初始队伍顺序为A学生132,B学生126,C学生187,D学生172,E学生126,F学生117

老师开始第一趟排序(升序)

首先老师先把A学生拉出队伍,与B学生进行比较,结果A>B,所以老师把B学生排到A学生的位置,把A学生排到B学生的位置;

再拉出A学生与C学生进行比较,结果A<C,所以老师把A学生还是排到B学生原来的位置上

再将C学生拉出队伍,与D学生进行比较,结果C>D,所以老师把D学生放到C学生原来位置,把C学生排到D学生的位置

再拉出C学生,再与E学生进行比较,结果C>E,所以老师把E学生排到C学生的位置,把C学生排到E学生的位置

再拉出C学生,与F学生进行比较,结果C>F,所以老师把F学生排到C学生的位置,把C学生排到F学生的位置,结束第一趟的排序,最后的队伍顺序为B学生126、A学生132、D学生172、E学生126、F学生117、C学生187,成功把最高的学生排到了最后一位,最后一位学生位置也就固定下来,不会再参与接下来的排序,而且此过程是有发生学生互换位置的,所以需要继续排序

老师开始第二趟排序,同理可得到最后的队伍顺序为B学生126、A学生132、E学生126、F学生117、D学生172、C学生187,成功把倒数第二高的学生排到了倒数第二位,并且最后两位学生也不会再参与接下来排序,而且此过程是有发生学生互换位置的,所以需要继续排序

老师开始第三趟排序,同理可得到最后的队伍排序为B学生126、E学生126、F学生117、A学生132、D学生172、C学生187,成功将最高的三位排到最后,并且不需要参与接下来的排序,而且此过程是有发生学生互换位置的,所以需要继续排序

老师开始第四趟排序,同理可得到最后的队伍排序为B学生126、F学生117、E学生126、A学生132、D学生172、C学生187,成功将最高的四位排到最后,并且不需要参与接下来的排序,而且此过程是有发生学生互换位置的,所以需要继续排序

老师开始第五趟排序(也是最后一趟排序6-1=5,不管有没有交换位置,都不再进行排序,同理可得到最后的队伍排序为F学生、B学生126、E学生、126、A学生132、D学生172、C学生187成功将最高的五位排到最后,此时只有一位学生在第一个位置,所以不需要再进行排序了。

四、冒泡排序的时间复杂度

1、最好情况,数据序列排序,只需一趟扫描,比较n次,没有数据移动,时间复杂度为O(n)

2、最坏情况,数据充列随机排列和反序排列,需要n-1趟扫描,比较次数和移动次数都是O(n^2),时间复杂度为O(n^2)

总之,数据序列越接近有序,冒泡排序算法时间效率越高,在O(n)到O(n^2)之间

五、冒泡排序的空间复杂度

冒泡排序需要一个辅助空间用于交换两个元素,空间复杂度为O(1)

六、稳定性

在冒泡排序算法中,关键字相等的元素会相遇进行比较,算法不改变它们的原有次序,所以,冒泡插入排序算法是稳定的。

七、小结

本博文从冒泡排序算法分析,升序和降序代码实现,老师排队的例子讲演,时间复杂度的2种情况,空间复杂度以及稳定性介绍了冒泡排序的方方面面。



如果有疑问或者对该博文有何看法或建议或有问题的,欢迎评论,恳请指正!

0 0