Java实现各种排序算法
由于现在工作,许多数同学是以java为语言基础去找工作,在此总结使用java实现的各种排序算法,以及每种排序的时间按复杂度等等知识点。
一、使用到的工具类
测试用类
public class SortingHelper {
// 构造方法私有化
private SortingHelper() {
}
// 验证 排序算法是否正确
public static <E extends Comparable<E>> boolean isSorted(E[] arr) {
for (int i = 1; i < arr.length; i++) {
if (arr[i - 1].compareTo(arr[i]) > 0)
return false;
}
return true;
}
/**
* 排序时间测试
* @param sortname 排序名称
* @param arr 传入数组
* @param <E> 泛型
*/
public static <E extends Comparable<E>> void sortTest(String sortname, E[] arr){
long startTime = System.nanoTime();
if (sortname.equals("SelectionSort")){
// 此处类名 选择 排序算法所在的类的名
Search.selectSort(arr, false);
}else {
}
long endTime = System.nanoTime();
double time = (endTime - startTime)/ 1000000000.0;
// 判断是否排除成功, 升序排列
if (!isSorted(arr)){
throw new RuntimeException(sortname + " failed=! ");
}
// 输出 排序测试信息
System.out.println(String.format("%s , n = %d : %f s ",
sortname,arr.length, time));
}
}
验证生成数据使用类
import java.util.Random;
public class ArrayGenerator {
private ArrayGenerator(){
}
// 生成一个随机数组,随机数组[0, n)
public static Integer[] generateOrderedArray(int n){
Integer[] arr = new Integer[n];
for (int i = 0; i < arr.length; i++) {
arr[i] = i;
}
return arr;
}
// 生成一个随机数组,数组长度为为n, 每个数字的范围是[0, bound)
public static Integer[] generateRandomArray(int n, int bound){
Integer[] arr = new Integer[n];
Random rand = new Random();
for (int i = 0; i < arr.length; i++) {
arr[i] = rand.nextInt(bound);
}
return arr;
}
}
二、排序
1.选择排序
时间复杂度:
O
(
n
2
)
O(n^2)
O(n2)
Java代码实现
/**
* 用于交换的两个元素
*
* @param data 传入的数组
* @param i 用于交换的元素的索引
* @param j 用于交换的元素的索引
*/
private static <E> void swap(E[] data, int i, int j) {
E temp = data[i];
data[i] = data[j];
data[j] = temp;
}
/***
* 选择排序
* @param data 输入的数组
* @param reverse 是否降序排列
* @return 返回排序好的数组
*/
public static <E extends Comparable<E>> E[] selectSort(E[] data, boolean reverse) {
for (int i = 0; i < data.length; i++) {
// 设 data数组中的最小值的索引为 i
int minIndex = i;
for (int j = i + 1; j < data.length; j++) {
if (reverse) { // 如果 reserve 为 true 则为升序排列
if (data[minIndex].compareTo(data[j]) < 0) {
minIndex = j;
}
} else { // 如果 reverse 为 false 则为降序排列
if (data[j].compareTo(data[minIndex]) < 0) {
minIndex = j;
}
}
}
if (i != minIndex) {
swap(data, i, minIndex);
}
}
return data;
}
测试代码
public static void main(String[] args) {
Integer[] data = {6, 4, 5, 3, 1, 2};
data = Search.selectSort(data, false);
for (int n : data) {
System.out.print(n + " ");
}
System.out.println();
Student zs = new Student();
zs.setId(1);
zs.setName("张三");
zs.setGrade(67);
Student ls= new Student();
ls.setId(2);
ls.setName("李四");
ls.setGrade(99);
Student[] students = {zs, ls};
Search.selectSort(students, false);
for (Student s : students) {
System.out.println(s);
}
int[] dataSize = {10000, 100000};
for (int n : dataSize) {
Integer[] arr1 = ArrayGenerator.generateRandomArray(n, n);
SortingHelper.sortTest("SelectionSort", arr1);
}
}
2.插入排序
时间复杂度:
O
(
n
2
)
O(n^2)
O(n2)
Java代码实现
public static <E extends Comparable<E>> void insertSort(E[] arr) {
for (int i = 0; i < arr.length; i++) {
for (int j = i; j > 0; j--) {
if (arr[j].compareTo(arr[j - 1]) < 0) {
swap(arr, j, j - 1);
} else {
break;
}
}
}
}
测试代码
public static void main(String[] args) {
Integer[] data = {6, 7, 4, 5, 3, 1, 2};
Search.insertSort(data);
for (int n : data) {
System.out.print(n + " ");
}
System.out.println();
Student zs = new Student();
zs.setId(1);
zs.setName("张三");
zs.setGrade(67);
Student ls= new Student();
ls.setId(2);
ls.setName("李四");
ls.setGrade(99);
Student[] students = {zgy, fbb};
Search.insertSort(students);
for (Student s : students) {
System.out.println(s);
}
int[] dataSize = {10000, 100000};
for (int n : dataSize) {
Integer[] arr1 = ArrayGenerator.generateRandomArray(n, n);
SortingHelper.sortTest("InsertionSort", arr1);
}
}
插入排序法的特性
当输入数据为有序或者接近有序时,插入排序的时间复杂度接近 O ( n ) O(n) O(n),性能相对于选择排序提升了非常多。二选择排序无论在什么情况下的时间复杂度都为$O(n^2)。