目录
Comparable接口
简单排序
冒泡排序
选择排序
插入排序
高级排序
希尔排序
概念
增常量h的确定
代码
时间复杂度
归并排序
快速排序
概念
代码
快速排序和归并排序的区别
时间复杂度
排序的稳定性
概念
稳定性的意义
稳定的排序算法
不稳定的排序算法
排序算法的选择
int h = 1;
while (h < a.length / 2) {
h = 2 * h + 1;
}
package lq.sort;
import org.junit.Test;
import java.util.Arrays;
/**
* @author LQ
* @create 2020-05-24 15:45
*/
public class Shell {
@Test
public void test() {
Integer[] arr1 = {8, 1, 0, 4, 1, 9, 45, 3, 7, 9, 10};
sort(arr1);
System.out.println(Arrays.toString(arr1));
}
public static void sort(Comparable[] a) {
//先求出增常量h的初始值
int h = 1;
while (h < a.length / 2) {
h = 2 * h + 1;
}
//希尔排序
while (h >= 1) {
//
/*
1 根据h的值分组, h是多少, 分组的个数就是多少
2 先假定h的值是3, 即当前分了3组, 从索引值是3的位置开始都是待插入的数, 然后我们依次遍历这些数, 遍历第一个数, 这个数就是属于
第一组的, 然后遍历到第二个数, 第二个数是属于第二组的, 然后遍历到第三个数, 第三个数是属于第三组的, 然后遍历到第四个数, 此时,
第四个数是属于第一组的, 即遍历到的第四个数是属于第一组的第二个数, 继续遍历, 知道遍历到数组的最后一个数, 排序完成!
*/
//找出待插入的数
for (int i = h; i < a.length; i++) {
for (int j = i; j >= h; j -= h) {
if (greater(a[j - h], a[j])) {
exchange(a, j - h, j);
} else {
break;
}
}
}
//减小h的值
h /= 2;
}
}
/**
* @param x
* @param y
* @return true: x>y
*/
public static boolean greater(Comparable x, Comparable y) {
return x.compareTo(y) > 0;
}
/**
* 交换数组中x和y的位置
* @param a
* @param x
* @param y
*/
public static void exchange(Comparable[] a, int x, int y) {
Comparable t;
t = a[x];
a[x] = a[y];
a[y] = t;
}
}
package lq.test;
import lq.sort.Insertion;
import lq.sort.Shell;
import org.junit.Test;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
/**
* @author LQ
* @create 2020-05-24 18:10
*/
public class TestShell {
@Test
public void test() throws IOException {
//创建数组
ArrayList arr = new ArrayList();
//将文件读取出来
BufferedReader reader = new BufferedReader(new InputStreamReader(TestShell.class.getClassLoader().getResourceAsStream("reverse_arr.txt")));
String line = null;
while ((line = reader.readLine()) != null) {
arr.add(Integer.parseInt(line));
}
//调用方法
Integer[] arr2 = new Integer[arr.size()];
arr.toArray(arr2);
testShell(arr2);
// testInsertion(arr2);
}
public void testShell(Integer[] a) {
//获取开始时的时间
long start = System.currentTimeMillis();
//排序
Shell.sort(a);
//获取结束时的时间
long end = System.currentTimeMillis();
System.out.println("Shell: " + (end-start) + " ms");
}
}
递归
概念
package lq.sort;
import org.junit.Test;
import java.util.Arrays;
/**
* @author LQ
* @create 2020-05-24 15:45
*/
public class Merge {
private static Comparable[] assist;
@Test
public void test() {
Integer[] arr1 = {8, 1, 0, 4, 1, 9, 45, 3, 7, 9, 10};
sort(arr1);
System.out.println(Arrays.toString(arr1));
}
public static void sort(Comparable[] a) {
//初始化辅助数组
assist = new Integer[a.length];
//找出开始和结束的索引值
int lo = 0;
int hi = a.length - 1;
//调用方法
sort(a, lo, hi);
}
public static void sort(Comparable[] a, int lo, int hi) {
//做安全检验
if (lo >= hi) {
return;
}
//求出中间位置的索引值
int mid = (lo + hi) / 2;
//递归调用
sort(a, lo, mid);
sort(a, mid + 1, hi);
//合并
merge(a, lo, mid, hi);
}
/**
* 归并算法的核心
*
* @param a
* @param lo
* @param mid
* @param hi
*/
public static void merge(Comparable[] a, int lo, int mid, int hi) {
//定义三个指针
int i = lo;
int p1 = lo;
int p2 = mid + 1;
//遍历, 移动指针p1 p2 i
while (p1 <= mid && p2 <= hi) {
if (less(a[p1], a[p2])) {
assist[i++] = a[p1++];
}else {
assist[i++] = a[p2++];
}
}
//如果p1指针还没有走完, 那直接吧剩余元素放大辅助数组中去
while (p1<=mid){
assist[i++] = a[p1++];
}
//如果p2指针还没有走完, 那直接吧剩余元素放大辅助数组中去
while (p2<=hi){
assist[i++] = a[p2++];
}
//将辅助数组的数据拷贝到原数组
for (int j = lo; j <=hi; j++) {
a[j]=assist[j];
}
}
/**
* @param x
* @param y
* @return true: x>y
*/
public static boolean less(Comparable x, Comparable y) {
return x.compareTo(y) < 0;
}
/**
* 交换数组中x和y的位置
*
* @param a
* @param x
* @param y
*/
public static void exchange(Comparable[] a, int x, int y) {
Comparable t;
t = a[x];
a[x] = a[y];
a[y] = t;
}
}
package lq.sort;
import org.junit.Test;
import java.util.Arrays;
/**
* @author LQ
* @create 2020-05-24 15:45
*/
public class Quick {
@Test
public void test() {
// Integer[] arr1 = {8, 1, 0, 4, 1, 9, 45, 3, 7, 9, 10};
Integer[] arr1 = {8, 2, 6, 0, 1, 4, 7, 9, 2, 1, 7, 78, 23, 56, 78, 12, 67, 2};
sort(arr1);
System.out.println(Arrays.toString(arr1));
}
public static void sort(Comparable[] a) {
int lo = 0;
int hi = a.length - 1;
sort(a, lo, hi);
}
public static void sort(Comparable[] a, int lo, int hi) {
//参数的合法性检验
if (lo >= hi) {
return;
}
//将左子组和右子组排序, 然后返回中间值的索引值
int partition = partition(a, lo, hi);
sort(a, lo, partition - 1);
sort(a, partition + 1, hi);
}
public static int partition(Comparable[] a, int lo, int hi) {
//定义左右指针
int left = lo;
int right = hi;
//
while (left < right) {
if (greater(a[left], a[left + 1])) {
exchange(a, left, left + 1);
left++;
} else {
exchange(a, left + 1, right);
right--;
}
}
return left;
}
/**
* @param x
* @param y
* @return true: x>y
*/
public static boolean less(Comparable x, Comparable y) {
return x.compareTo(y) < 0;
}
public static boolean greater(Comparable x, Comparable y) {
return x.compareTo(y) > 0;
}
/**
* 交换数组中x和y的位置
*
* @param a
* @param x
* @param y
*/
public static void exchange(Comparable[] a, int x, int y) {
Comparable t;
t = a[x];
a[x] = a[y];
a[y] = t;
}
}