版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
三种简单的排序算法:时间复杂度为 级别的,分别是冒泡排序、选择排序及插入排序。
工具类
package my.algorithm;
public class Utils {
// 生成一个长度为n的随机数组,范围是[rangeL, rangeR]
// Math.random()生成一个(0,1)的数
public static int[] generateRandArray(int n, int rangeL, int rangeR) {
assert rangeL <= rangeR;
int[] array = new int[n];
for (int i = 0; i < n; i++) {
// (rangeR - rangeL + 1)是区间长度
array[i] = (int) (Math.random() * (rangeR - rangeL + 1) + rangeL);
}
return array;
}
/**
* 打印数组
* @param array array
*/
public static void printArray(int[] array) {
for (int i = 0; i < array.length; i++) {
if (i == 0) System.out.print("[");
if (i < array.length - 1) System.out.print(array[i] + ", ");
if (i == array.length - 1) System.out.println(array[i] + "]");
}
}
/**
* 判断数组是否升序排列
* @param array array
* @return isOrdered
*/
public static boolean isAcsOrdered(int[] array) {
for (int i = 0; i < array.length; i++) {
if (array[i] > array[i + 1]) {
return false;
}
}
return true;
}
}
冒泡排序
package my.algorithm;
public class BubbleSort {
/**
* 冒泡排序
* 时间复杂度为O(n2),是稳定的排序算法
* @param array array
* @return sorted array
*/
private static int[] bubble(int[] array) {
for (int i = 0; i < array.length; i++) {
for (int j = 0; j < array.length - 1 - i; j++) {
// 如果前面的比后面的大,就冒泡出来。大的冒泡到后面。
// 内层每循环一次就有一个冒出来
if (array[j] > array[j+1]) {
int tmp = array[j];
array[j] = array[j + 1];
array[j + 1] = tmp;
}
}
}
return array;
}
public static void main(String[] args) {
int[] array = Utils.generateRandArray(10,1,100);
Utils.printArray(array);
Utils.printArray(bubble(array));
}
}
插入排序
package my.algorithm;
import java.util.Arrays;
public class InsertionSort {
public static int[] insertSort_v1(int[] array) {
for (int i = 1; i < array.length; i++) {
for (int j = i; j > 0; j--) {
if (array[j - 1] > array[j]) {
int tmp = array[j];
array[j] = array[j-1];
array[j-1] = tmp;
} else {
break;
}
}
}
return array;
}
public static int[] insertSort_v2(int[] array) {
for (int i = 1; i < array.length; i++) {
//这里是把break合到for循环对j的判断上来了,如果前面的值已经比现在的小了
//说明更前面的会更小,就没有必要再比下去了。没有必要再比下去了。
for (int j = i; j > 0 && array[j - 1] > array[j]; j--) {
int tmp = array[j];
array[j] = array[j-1];
array[j-1] = tmp;
}
}
return array;
}
/**
* 第三版的优化:是把交换优化为覆盖,最后只交换一次!
* @param array
* @return
*/
public static int[] insertSort_v3(int[] array) {
for (int i = 1; i < array.length; i++) {
int e = array[i];
int j;
//注意,这里是大于e,而不是array[j]
for (j = i; j > 0 && array[j - 1] > e; j--) {
array[j] = array[j - 1];
}
array[j] = e;
}
return array;
}
public static void main(String[] args) {
int[] array = Utils.generateRandArray(10,0,100);
int[] array2 = Arrays.copyOf(array,array.length);
Utils.printArray(array2);
int[] array3 = Arrays.copyOf(array,array.length);
System.out.println(Utils.isAcsOrdered(array2));
System.out.println(Utils.isAcsOrdered(array3));
Utils.printArray(insertSort_v1(array));
Utils.printArray(insertSort_v2(array2));
Utils.printArray(insertSort_v3(array3));
}
}
选择排序
package my.algorithm;
/**
* 选择排序,思路是假设第一个是最大值,从第二数到所最后一个分别与第一个数比较大小,
* 如果比第一个数大,则进行交换。
* 然后再假设第二个数是第二大的数,从三个数到最后一个数分别与第二个数进行比较,如果比第二个数大,则进行交换,
* 这样就可以找到第二大的数。
* 以此类推,将所有数据进行排序。
* 从小到大排序
*/
public class SelectionOrder {
private static int[] select_v1(int[] array) {
for (int i = 0; i < array.length; i++) {
for (int j = i + 1; j < array.length; j++) {
if (array[j] < array[i]) {
int temp = array[i];
array[i] = array[j];
array[j] = temp;
}
}
}
return array;
}
private static int[] select_v2(int[] array) {
for (int i = 0; i < array.length; i++) {
int minIndex = i;
for (int j = i + 1; j < array.length; j++) {
if (array[j] < array[minIndex]) {
minIndex = j;
}
}
//找到最小值的index后,与位置于i值交换,交换的次数最多为n次
int tmp = array[i];
array[i] = array[minIndex];
array[minIndex] = tmp;
}
return array;
}
public static void main(String[] args) {
int[] array = Utils.generateRandArray(10,1,100);
Utils.printArray(array);
//int[] array_v1 = select_v1(array);
//Utils.printArray(array_v1);
int[] array_v2 = select_v2(array);
Utils.printArray(array_v2);
}
}