可以思考一件事:
大家都知道六个数需要进行五轮比较,那么当你在第三轮就已经将所有的数有序排列了,剩下的两轮是否就比较多余???
同时还可以思考下:
如int[ ] arr={7 1 2 3 4 5 6};
大家可以看到除了第一个数后面都是有序的:
按照现有的逻辑,有序区的长度和排序的轮数是相等的。例如第1轮排序过后的有序区长度是1,第2轮排序过后的有序区长度是2 ……实际上,数列真正的有序区可能会大于这个长度,如上述例子中在第2轮排序时,后面的5个元素实际上都已经属于有序区了。因此后面的多次元素比较是没有意义的。那么,该如何避免这种情况呢?我们可以在每一轮排序后,记录下来最后一次元素交换的位置,该位置即为无序数列的边界,再往后就是有序区了。
package study.test08;
import java.util.Arrays;
public class Sort {
public static void main(String[] args) {
int[] arr = new int[]{5, 8, 6, 33, 9, 2, 1, 7};
sort(arr);
System.out.println(Arrays.toString(arr));
}
public static void sort(int arr[]) {
//记录最后一次交换的位置
int lastExchangeIndex = 0;
//无序数列的边界,每次比较到这里位置为止
int sortBorder = arr.length - 1;
for (int i = 0; i < arr.length - 1 ; i++) {
boolean isSorted = true;
for (int j = 0; j < sortBorder; j++) {
int temp = 0;
if (arr[j] > arr[j + 1]) {
temp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = temp;
isSorted = false;
lastExchangeIndex=j;
}
}
sortBorder=lastExchangeIndex;
if (isSorted) {
break;
}
}
}
}
sortBorder就是无序数列的边界。在每一轮排序过程中,处于 sortBorder之后的元素就不需要再进行比较了,肯定是有序的。
以下是冒泡排序的基本示意图:
对于{2,3,4,5,6,1,7,8}来说以上就是基本的冒泡排序,需要比较七轮
比较下鸡尾酒排序:
对于鸡尾酒排序来说,排序过程就像钟摆一样,第1轮从左到右,第2轮从右到左,第3轮再从左到右。
package study.test08;
import java.util.Arrays;
public class SortMax {
public static void sort(int arr[]) {
int temp = 0;
for (int i = 0; i < arr.length / 2; i++) {
boolean isSorted = true;
for (int j = i; j < arr.length - i - 1; j++) {
if (arr[j] > arr[j + 1]) {
temp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = temp;
isSorted = false;
}
}
if (isSorted) {
break;
}
isSorted = true;
for (int j = arr.length - i - 1; j > i; j--) {
if (arr[j] < arr[j - 1]) {
temp = arr[j];
arr[j] = arr[j - 1];
arr[j - 1] = temp;
isSorted = false;
}
}
if (isSorted) {
break;
}
}
}
public static void main(String[] args) {
int[] arr = new int[]{5, 8, 6, 33, 9, 2, 1, 7};
sort(arr);
System.out.println(Arrays.toString(arr));
}
}
今天好好学习了吗