排序算法,基本的高级语言都有一些提供。C语言有qsort()函数,C++有sort()函数,java语言有Arrays类(不是Array)。用这些排序时,都可以写自己的排序规则。
Java API对Arrays类的说明是:此类包含用来操作数组(比如排序和搜索)的各种方法。
上面两句话话是对其他博客上的引用,不清楚是那篇了,所以就不贴地址了,其实除了数组,java对集合也有sort()的排序方法,这里详细写一下对数组的几种常用的排序方法。
快速排序是对选择排序和冒泡排序的优化
选择排序我觉得是最好理解的,冒泡排序推荐看下:https://www.cnblogs.com/shen-hua/p/5422676.html,写的很清楚
冒泡排序:
@Test
public void test4() {
int a[] = {49, 38, 65, 97, 76, 13, 27, 49, 78, 34, 12, 64, 5, 4, 62, 99, 98, 54, 56, 17, 18, 23, 34, 15, 35, 25, 53, 51};
for(int i=0;i<a.length-1;i++) {
for (int j = 0; j < a.length - 1-i; j++) {
if (a[j] > a[j + 1]) {
int t = a[j];
a[j] = a[j + 1];
a[j + 1] = t;
}
}
}
System.out.println(Arrays.toString(a));
}
选择排序:
@Test
public void test2() {
int a[] = {49, 38, 65, 97, 76, 13, 27, 49, 78, 34, 12, 64, 5, 4, 62, 99, 98, 54, 56, 17, 18, 23, 34, 15, 35, 25, 53, 51};
for (int i = 0; i < a.length; i++) {
for (int j = i + 1; j < a.length; j++) {
if (a[i] > a[j]) {
a[j] = a[i] + a[j];
a[i] = a[j] - a[i];
a[j] = a[j] - a[i];
}
}
}
递归排序:递归的本质---自身调用自身
# 求阶乘
public static void main(String[] args) {
System.out.println(f(5));
System.out.println(5 * 4 * 3 * 2 * 1);
}
public static int f(int n) {
if (1 == n || 2 == n)
return n;
else
return n * f(n - 1);
/*
* 5*f4
* 5*4*f3
* 5*4*3*f2
* 5*4*3*2
* */
}
/*
斐波那契数列: 0、1、1、2、3、5、8
f0 = 0; f1 = 1; fn = f(n-1) + f(n - 2) (n >= 2)
*/
public static void main(String[] args) {
System.out.println(f(5));
}
public static int f(int n) {
if (n == 1 || n == 2) {
return 1;
} else {
return f(n - 1) + f(n - 2);
}
}
快速排序分治法就用到了递归思想,主要有挖坑法和下标交换法,分治也用到交换思想,
挖坑法
package study.test;
import java.util.Arrays;
public class Mysort {
public static void quickSort(int[] arr, int startIndex, int endIndex) {
// 递归结束条件:startIndex大等于endIndex的时候(即每部分数组拆分至一个元素)
if (startIndex >= endIndex) {
return;
}
// 得到基准元素位置
int pivotIndex = partition(arr, startIndex, endIndex);
// 用分治法递归数列的两部分
quickSort(arr, startIndex, pivotIndex - 1);
quickSort(arr, pivotIndex + 1, endIndex);
}
private static int partition(int[] arr, int startIndex, int endIndex) {
System.out.println("the begin : " + Arrays.toString(arr));
// 取第一个位置的元素作为基准元素
int pivot = arr[startIndex];
int left = startIndex;
int right = endIndex;
// 坑的位置,初始等于pivot的位置
int index = startIndex;
//大循环在左右指针重合或者交错时结束
while (right >= left) {
//right指针从右向左进行比较
while (right >= left) {
if (arr[right] < pivot) {
arr[left] = arr[right];
index = right;
left++;
break;
}
right--;
System.out.println("the in one: " + Arrays.toString(arr));
}
//left指针从左向右进行比较
while (right >= left) {
if (arr[left] > pivot) {
arr[right] = arr[left];
index = left;
right--;
break;
}
left++;
System.out.println("the in two: " + Arrays.toString(arr));
}
}
arr[index] = pivot;
System.out.println("the end : " + Arrays.toString(arr));
return index;
}
public static void main(String[] args) {
int[] arr = new int[]{4, 7, 6, 5, 3, 2, 8, 1};
quickSort(arr, 0, arr.length - 1);
System.out.println(Arrays.toString(arr));
}
}
非交换思想,使用数组拆分
package study.test;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
public class JustSort {
public static int partition(int[] arr, int start, int end) {
int mid = start + (end - start) / 2; //每次取中位数为基准元素
System.out.println("基准元素取中 mid :" + arr[mid]);
List<Integer> left = new ArrayList();
List<Integer> rigth = new ArrayList();
for (int i = 0; i <= end; i++) { //遍历数组,使用集合分别存储大于基准数和小于基准数的元素
if (i != mid) { //遍历过错中先隔离基准数,待遍历完毕后存储基准数,保证基准数在数组中下标不变
if (arr[i] <= arr[mid]) {
left.add(arr[i]);
}
if (arr[i] > arr[mid]) {
rigth.add(arr[i]);
}
}
}
int index = left.size(); //获取数组分治后下一轮数组的长度作为下一次排序的范围
left.add(arr[mid]); //添加基准数
left.addAll(rigth); //此时left集合中存储当次排序后元素
for (int i = 0; i < left.size(); i++) {
arr[i] = left.get(i); //将排序后元素从list更新到原数组
}
System.out.println(Arrays.toString(arr));
return index;
}
public static void sort(int[] array, int start, int end) {
if (start >= end) { //当拆分数组元素仅有1个时,出现截取数组终止下标比开始下标小1或者相等(第一个元素时相等),此时无需排序
return;
}
int mid = partition(array, start, end);
sort(array, start, mid - 1); //根据基准数切割数组,选取基准数左边数组
sort(array, mid + 1, end); //选取基准数右边数组
}
public static void main(String[] args) {
int[] arr = {4, 7, 6, 5, 3, 2, 8, 1};
System.out.println("源数组: \n" + Arrays.toString(arr));
sort(arr, 0, arr.length - 1);
System.out.println("排序结果: \n" + Arrays.toString(arr));
}
}