选择排序 冒泡排序
public static void main(String[] args){
int arr[] = {
3,5,7,2,8,1,9,6,4};
System.out.print("排序前:");printfArray(arr);
selectSort(arr);
System.out.print("选择排序后:");printfArray(arr);
int arr2[] = {
3,5,7,2,8,1,9,6,4};
System.out.print("排序前:");printfArray(arr2);
bubbleSort(arr2);
System.out.print("冒泡排序后");printfArray(arr2);
}
public static void selectSort(int[] arr){
for(int x=0; x<arr.length-1; x++){
for(int y=x+1; y<arr.length; y++){
if(arr[x]>arr[y]){
int temp = arr[x];
arr[x] = arr[y];
arr[y] = temp;
}
}
}
}
public static void bubbleSort(int[] arr){
for(int x=0;x<arr.length-1;x++){
for(int y=0;y<arr.length-1-x;y++){
if(arr[y]>arr[y+1]){
int temp = arr[y+1];
arr[y+1] = arr[y];
arr[y] = temp;
}
}
}
}
public static void printfArray(int[] arr){
System.out.print("[");
for(int i=0;i<arr.length;i++){
if(i!=arr.length-1){
System.out.print(arr[i]+",");
}else{
System.out.println(arr[i]+"]");
}
}
}
冒泡排序优化
public static void bubbleSort2(int[] arr){
for(int x=0;x<arr.length-1;x++){
boolean isSorted = true;
for(int y=0;y<arr.length-1-x;y++){
if(arr[y]>arr[y+1]){
int temp = arr[y+1];
arr[y+1] = arr[y];
arr[y] = temp;
isSorted = false;
}
}
if(isSorted){
break;
}
}
}
3,4,2,1,5,6,7,8
这个数列的特点是前半部分(3,4,2,1)无序,后半部分(5,6,7,8)升序,并且后半部分的元素已经是数列最大值。
其实一部分已经是有序的了,不需要重复进行遍历比较了。
这个问题的关键点在哪里呢?关键在于对数列有序区的界定。
按照现有的逻辑,有序区的长度和排序的轮数是相等的。比如第一轮排序过后的有序区长度是1,第二轮排序过后的有序区长度是2 ......
实际上,数列真正的有序区可能会大于这个长度,比如例子中仅仅第二轮,后面5个元素实际都已经属于有序区。因此后面的许多次元素比较是没有意义的。
如何避免这种情况呢?我们可以在每一轮排序的最后,记录下最后一次元素交换的位置,那个位置也就是无序数列的边界,再往后就是有序区了。
public static void bubbleSort3(int arr[], int len) {
int i = 0;
int tmp = 0;
int flag = 0;
int pos = 0;
int k = len - 1;
for (i = 0; i < len - 1; i++){
pos = 0;
int j = 0;
flag = 0;
for (j = 0; j < k; j++){
if (arr[j]>arr[j + 1]){
tmp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = tmp;
flag = 1;
pos = j;
}
}
if (flag == 0){
return;
}
k = pos;
}
}