冒泡排序
冒泡排序的英文是bubble sort,它是一种基础的交换排序。
原理简单说就是每一个元素都像气泡一样根据自身大小一个一个的往上升。数组之间的元素两两比较,交换顺序,重复遍历数组直到排好序为止。
最简单的冒泡排序算法实现:
public void sort(int[] array) {
int count = 0;
for (int i = 0; i < array.length - 1; i++) {
for (int j = 0; j < array.length - i - 1; j++) {
if (array[j] > array[j + 1]) {
int temp = array[j];
array[j] = array[j + 1];
array[j + 1] = temp;
}
}
count++;
}
System.out.println("比较轮次:" + count);
}
public static void main(String[] args) {
int[] array = new int[10000];
Random random =new Random(100);
for(int i=0;i<10000;i++){
array[i]=random.nextInt(10000);
}
//计时开始
long start = System.currentTimeMillis();
BubbleSort bubbleSort =new BubbleSort();
bubbleSort.sort(array);
//计时结束
long end = System.currentTimeMillis();
System.out.println("共耗时"+(end-start)+"毫秒");
for(int i=0;i<array.length;i++){
System.out.print(array[i]+" ");
}
}
结果:
冒泡排序优化
最基础的冒牌排序需要比较 array.length-1 轮,但是有时候不需要比较那么多轮次就排好序了,所以这就需要优化代码:
public void sort(int[] array) {
int count = 0;
for (int i = 0; i < array.length - 1; i++) {
boolean isSorted = true;
for (int j = 0; j < array.length - i - 1; j++) {
if (array[j] > array[j + 1]) {
int temp = array[j];
array[j] = array[j + 1];
array[j + 1] = temp;
isSorted=false;
}
}
if(isSorted){
break;
}
count++;
}
System.out.println("比较轮次:" + count);
}
每一轮比较开始都设 isSorted 为 true,只要交换次序了就说明还没排好序,所以将 isSorted 设置为 false,当一轮循环过后,isSorted 还是 true,说明此时数组已经排好序了,退出循环即可。
冒泡排序第一轮遍历数组之后,最大的元素就会跑到数组最后面,第二轮过后,第二大的元素就会跑到数组倒数第二个,依此类推。但是有一个问题,就是经过几轮排序之后,数组后面的元素已经排好序了(或者数组初始化的时候后面的元素就是排好序的)但是每轮还是要全部遍历,所以代码还需要继续优化:
public void sort(int[] array) {
int count = 0;
int lastExchangeIndex =0;
int compareBorder = array.length - 1;
for (int i = 0; i < array.length - 1; i++) {
boolean isSorted = true;
for (int j = 0; j < compareBorder; j++) {
if (array[j] > array[j + 1]) {
int temp = array[j];
array[j] = array[j + 1];
array[j + 1] = temp;
isSorted = false;
lastExchangeIndex = j;
}
}
compareBorder = lastExchangeIndex;
if (isSorted) {
break;
}
count++;
}
System.out.println("比较轮次:" + count);
}
利用 lastExchangeIndex 记录最后交换次序的数组边界索引,下次循环后面的就不需要遍历了。
冒泡排序升级版之鸡尾酒排序
鸡尾酒排序的元素比较和交换是双向的,而冒泡是单向的,直接上代码:
public void sort(int[] array) {
int count = 0;
for (int i = 0; i < array.length / 2; i++) {
boolean isSorted = true;
//从左边开始扫描的最后一次交换索引
int leftLastExChangIndex = 0;
//从右边开始扫描的最后一次交换索引
int rightLastExChangIndex = 0;
for (int j = rightLastExChangIndex; j < array.length - 1; j++) {
if (array[j] > array[j + 1]) {
int temp = array[j];
array[j] = array[j + 1];
array[j + 1] = temp;
isSorted = false;
leftLastExChangIndex = j;
}
}
count++;
if (isSorted) {
break;
}
isSorted = true;
for (int j = leftLastExChangIndex; j > 0; j--) {
if (array[j] < array[j - 1]) {
int temp = array[j];
array[j] = array[j - 1];
array[j - 1] = temp;
isSorted = false;
rightLastExChangIndex = j;
}
}
count++;
if (isSorted) {
break;
}
}
System.out.println("比较轮次:" + count);
}
运行结果:
个人博客:冒泡排序及升级版鸡尾酒排序