八大排序里面经常让写的两个就是快排和冒泡,面试经常会遇到,mark一下。
冒泡,两个两个比较,前一个大于后一个,则把大的挪到后面,第一趟有n个元素,需要比较n-1次;第二趟n-1个元素,比较n-2次。所以,内层循环是length-i 再-1。
public static void main(String[] args){
int[] arr = {1,5,3,8,4,9,5,5,6,7,2,88,54,666,47};
for(int i = 0; i < arr.length; i++){
for(int j = 0; j < arr.length - i - 1 ;j++){
if(arr[j] > arr[j+1]){
int temp = arr[j];
arr[j] = arr[j+1];
arr[j+1] = temp;
}
}
}
for(int i =0; i< arr.length;i++){
if(i == arr.length-1){
System.out.print(arr[i]+",");
}else{
System.out.print(arr[i]);
}
}
}
快排
快排的思想是这样:arr为待排序数组,传入的值为arr,low,high。
每一轮,都需要调用一次quciksort
- 每轮排序都把第一个元素作为基准,记为pivot。每一轮我们都要做到让arr[pivot]左边的元素全小于arr[pivot],右边的全大于arr[piovt]。这样arr[pivot]就不用排序了,只需要递归地排序arr坐边和右边的两个序列,即调用quickSort(arr, low, pivot - 1)和quickSort(arr, pivot + 1, high)即可。
- 每一轮内的思路为,遍历坐标i的元素,直到遇到第一个大于arr[povit]的元素,否则i++。遍历坐标j的元素,直到遇到一个小于arr[povit],否则j++。因为后面递归的时候需要用到low和high,不希望low和high被改变,所以循环的时候用i和j替代low和high,循环的条件是 i<j ,这里不能取等。
每一轮的具体操作如下
取两个下标i和j,其中i为arr的起始元素,j为末尾元素。
循环的时候不用for循环,而是去用while(),while()内的循环条件不仅要保证arr[j] > arr[pivot] 且还需要保证 i<j.
比较arr[j] 和arr[pivot] 的值,arr[i] 和arr[pivot] 的值。
这个时候得到了i和j的值,需要进行交换,但交换之前需要判断一下i是否小于j,是的话继续循环,i=j的时候循环结束,此时i<j。因为可能会出现i和j碰头之后,继续向前走的情况,即i等于j,这时说明不用交换,pivot左边的数已经全部小于arr[pivot]的值了,且右边的值全部大于arr[pivot]。
这时i就是小于pivot的值,交换arr[i] 和arr[pivot]
package JZOffer;
import java.util.*;
public class Solution2 {
public static void main(String[] args){
int[] arr1 = new int[]{1332802,1177178,1514891,871248,753214,123866,1615405,328656,1540395,968891,1884022,252932,1034406,1455178,821713,486232,860175,1896237,852300,566715,1285209,1845742,883142,259266,520911,1844960,218188,1528217,332380,261485,1111670,16920,1249664,1199799,1959818,1546744,1904944,51047,1176397,190970,48715,349690,673887,1648782,1010556,1165786,937247,986578,798663};
int[] arr2 = new int[]{1332802,1177178,1514891,871248,753214,123866,1615405,328656,1540395,968891,1884022,252932,1034406,1455178,821713,486232,860175,1896237,852300,566715,1285209,1845742,883142,259266,520911,1844960,218188,1528217,332380,261485,1111670,16920,1249664,1199799,1959818,1546744,1904944,51047,1176397,190970,48715,349690,673887,1648782,1010556,1165786,937247,986578,798663};
quickSort1(arr1, 0, arr1.length - 1);
for (int a:arr1) {
System.out.print(a+",");
}
System.out.println();
quickSort2(arr2, 0, arr2.length - 1);
for (int b:arr2) {
System.out.print(b+",");
}
}
public static void quickSort1(int[] arr, int low, int high){
if(low >= high) return;
int p = arr[low];
int i = low;
int j = high;
int temp;
while(i < j){
while(p <= arr[j] && i < j){
j--;
}
while(p >= arr[i] && i < j){
i++;
}
if(i < j){
temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
}
arr[low] = arr[i];
arr[i] = p;
quickSort1(arr, low, i-1);
quickSort1(arr, i+1, high);
}
public static void quickSort2(int[] arr, int low, int high){
if(low >= high) return;
int p = arr[low];
int i = low;
int j = high;
while(i < j){
while(p <= arr[j] && i < j){
j--;
}
arr[i] = arr[j];
while(p >= arr[i] && i < j){
i++;
}
arr[j] = arr[i];
}
arr[i] = p;
quickSort2(arr, low, i-1);
quickSort2(arr, i+1, high);
}
}