排序系列之——冒泡排序

 1.算法思想:

          冒泡排序是每次将最大(正序)或最小(逆序)的元素像我们的泡泡一样“冒”到序列末尾,直到整体有序为止。我们先来看看如下的过程:

比如我将 3,2,5,1,4从小到大排序

第一趟排序:

             3比2大所以2,3交换位置得到 2,3,5,1,4

             然后轮到3,5比较,3比5小不做交换

             然后轮到5,1比较,5比1大 1,5交换位置 得到2,3,1,5,4

             然后轮到5,4比较,5比4大,交换位置 得到2,3,1,4,5

如上结果可以看到 最大的5已结被“冒泡”到最末尾,下一轮排序的时候我们只需要轮询到4的位置,按照上述步骤循环,最后即可得到排序好的序列。

普通冒泡排序代码如下:

public void bubbleSort(int[] arr){
    for(int i=0;i<arr.length;i++){
        for(int j = 0;j< arr.length-i && j+1 <arr.length;j++){
              if(arr[j]>arr[j+1]){
                  int tem=arr[j];
                  arr[j]=arr[j+1];
                  arr[j+1]=tem;
              }
        }
    }
}

        但是想过没有,如果我们要排序的序列基本有序,我们经过几轮排序之后整个序列就有序了,那么我们还要继续遍历比较是不是就浪费了?那么有什么办法能避免这样的无用功呢?答案就是如果发现在某一趟排序中没有位置交换的话,那么我们就可以判定我们的序列已经被排好序了,如下是经过优化后的冒泡排序算法,通过设置标志位flag来判断某趟排序是否发生位置交换,如果没有则跳出外层循环。考虑到我们要排序的可能不只是基本数据类型int,所以如下代码采用java的泛型实现。

2.代码清单:

package Sort;

import java.util.Arrays;

/**
 * @author xuyp 优化的冒泡排序
 */
public class BubbleSort {

	public static <T extends Comparable<T>> T[] sort(T[] t) {
		for (int i = 0; i < t.length; i++) {
			boolean flag = true;//当没有发生交换 flag 为 true
			for (int j = 0; j < t.length - i && j + 1 < t.length; j++) {
				if (t[j].compareTo(t[j + 1]) > 0) {
					T tem = t[j];
					t[j] = t[j + 1];
					t[j + 1] = tem;
					flag = false;//发生交换 设置为false
				}
			}
			if(flag) break;//当没有发生交换,说明已经有序了 直接退出
		}
		return t;
	}

	public static void main(String[] args) {
		Integer[] iarr = { 3, 2, 1, 5, 4 };
		iarr = sort(iarr);
		System.out.println(Arrays.toString(iarr));

		String[] sarr = { "a", "d", "c", "b" };
		sarr = sort(sarr);
		System.out.println(Arrays.toString(sarr));

		Student[] stus = { new Student("d", 17), new Student("b", 18),
				new Student("a", 18), new Student("c", 20) };
		stus=sort(stus);
		System.out.println(Arrays.toString(stus));
	}
}

Student:

package Sort;

public class Student implements Comparable<Student> {
	String name;
	int age;

	public Student(String name, int age) {
		this.name = name;
		this.age = age;
	}

	@Override
	public int compareTo(Student o) {//先按名字name排,然后按年龄age排
		int res = this.name.compareTo(o.name);
		if (res == 0) {
			return this.age - o.age;
		}
		return res;
	}

	public String toString() {
		return name + ":" + age;
	}
}

3.运行结果:

猜你喜欢

转载自blog.csdn.net/sinat_22808389/article/details/81566433