1. 冒泡排序进阶之路
/**
* 最简单的交换排序:每个数与之后的所有数比较
* @param arr
*/
public void simpleSort(int[] arr){
for (int i = 0; i < arr.length; i++) {
for (int j = i+1; j < arr.length; j++) {
if(arr[i] > arr[j]){
swap(arr, i, j);
}
}
}
}
/**
* 正宗的冒泡排序:每次从最后开始找出最小的数放在最前面,最小的数像气泡一样慢慢浮出水面
* @param arr
*/
public void bubbleSort(int[] arr){
for (int i = 0; i < arr.length; i++) {
for (int j = arr.length-1; j > i; j--) {
if(arr[j] < arr[j-1]){
swap(arr, j, j-1);
}
}
}
}
/**
* 进阶的冒泡排序:增加状态flag判断,若已经交换过则不再进行排序,这样已经排好序的序列就没必要做剩下几次的遍历
* @param arr
*/
public void bubbleSortAdvanced(int[] arr){
boolean flag = true;
for (int i = 0; i < arr.length && flag; i++) {//若上一轮未进行交换则说明该序列已经有序
flag = false;//每一轮都初始化为false
for (int j = arr.length-1; j > i; j--) {
if(arr[j] < arr[j-1]){
swap(arr, j, j-1);
flag = true;
}
}
}
}
public void swap(int[] arr, int i, int j){
int temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
2.简单选择排序
/**
* 简单选择排序算法:每次寻找除第i个数字之外其余数字中最小的数之后,将最小的数与第i个数交换
* @param arr
*/
public void sort(int[] arr){
int min;
for (int i = 0; i < arr.length; i++) {
min = i;
for (int j = i+1; j < arr.length; j++) {
if(arr[min] > arr[j]){
min = j;
}
}
if(min != i){
swap(arr, min, i);
}
}
}
public void swap(int[] arr, int i, int j){
int temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
3.直接插入排序
/**
* 直接插入排序算法:arr[0]作为哨兵,从第二位开始,找到相邻两数中的小的拎出来给arr[0],再把比它大的依次后移,
* 最后将arr[0]的值赋给空出来的,这样小数就排在了前面
* @param arr
*/
public void sort(int[] arr){
int i,j;
for (i = 2; i < arr.length; i++) {
if(arr[i] < arr[i-1]){
arr[0] = arr[i]; //arr[0]为哨兵
for (j = i-1; arr[j] > arr[0]; j--) {
arr[j+1] = arr[j];
}
arr[j+1] = arr[0];
System.out.println(Arrays.toString(arr));
}
}
}
3.快速排序
/**
* 快速排序:整个数组进行递归调用。
* 假设第一个数作为基准,每次递归都将小于基准数的放到其左边,大于的放到右边;之后左边和右边的数列再进行这样的递归调用,直到真个数列有序。
* @param arr
*/
public void quickSort(int arr[]){
sort(arr, 0, arr.length-1);
}
/**
* 递归方法
* @param arr
* @param low
* @param high
*/
public void sort(int arr[], int low, int high){
if(low < high){
int pivot = partition(arr, low, high);
sort(arr, low, pivot-1);
sort(arr, pivot+1, high);
}
}
/**
* 获取切分点的索引,并将小于基准值的数都放到左侧,大于基准值的数都放到右侧。
* @param arr
* @param low
* @param high
* @return
*/
public int partition(int arr[], int low, int high){
int pivot = arr[low];
while(low < high){
while(low < high && pivot <= arr[high]){
high--;
}
swap(arr, low, high);
while(low < high && pivot >= arr[low]){
low++;
}
swap(arr, low, high);
}
return low;
}
public void swap(int[] arr, int i, int j){
int temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
对于数列: {50, 10, 90, 30, 70, 40, 80, 60, 20}
执行如下:
此时,基准值50左侧的数均比它小,右侧的均比它大,则完成第一次递归调用,接下来再进行左右两侧分别递归,直至整个数列有序。