常见排序(带输入)和对数器测试(不带输入)
1、冒泡排序
package 苟熊岭熊哒;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Arrays;
//冒泡排序
public class BubbleSort {
public static void swap(int[] arr, int i, int j) {
int tmp = arr[i];
arr[i] = arr[j];
arr[j] = tmp;
}
public static void bubbleSort(int[] arr) {
if (arr == null || arr.length < 2) {
return;
}
for (int i = 0; i < arr.length - 1; i++) {
for (int j = 0; j < arr.length - 1 - i; j++) {
if (arr[j + 1] < arr[j]) {
swap(arr, j + 1, j);
}
}
}
}
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
System.out.println("请输入元素个数:");
int n = Integer.parseInt(br.readLine());
int[] arr = new int[n];
System.out.println("请输入元素内容(每个元素之间用空格分隔):");
String[] line = br.readLine().split(" ");
for (int i = 0; i < line.length; i++) {
arr[i] = Integer.parseInt(line[i]);
}
bubbleSort(arr);// 冒泡排序
System.out.println("排序后:" + Arrays.toString(arr));
}
}
输出结果:
对数器测试
package 苟熊岭熊哒;
import java.util.Arrays;
//冒泡排序
public class BubbleSort {
// 交换
public static void swap(int[] arr, int i, int j) {
int tmp = arr[i];
arr[i] = arr[j];
arr[j] = tmp;
}
// 用系统提供的方式进行排序
public static void comparator(int[] arr) {
Arrays.sort(arr);
}
// 生成一个随机数组
public static int[] generateRandomArray(int maxSize, int maxValue) {
int[] arr = new int[(int) ((maxSize + 1) * Math.random())];
for (int i = 0; i < arr.length; i++) {
arr[i] = (int) ((maxValue + 1) * Math.random()) - (int) ((maxValue + 1) * Math.random());
}
return arr;
}
// 拷贝数组
public static int[] copyArray(int[] arr) {
if (arr == null) {
return null;
}
int[] res = new int[arr.length];
for (int i = 0; i < arr.length; i++) {
res[i] = arr[i];
}
return res;
}
// 判断arr1和arr2中的每个值是否相等
public static boolean isEqual(int[] arr1, int[] arr2) {
int i = 0;
while (i < arr1.length) {
if (arr1[i] == arr2[i]) {
i++;
} else {
return false;
}
}
return true;
}
// 打印数组
public static void printArray(int[] arr) {
for (int i = 0; i < arr.length; i++) {
System.out.print(arr[i] + " ");
}
}
// test
// 冒泡排序
public static void bubbleSort(int[] arr) {
if (arr == null || arr.length < 2) {
return;
}
// for(int i=arr.length-1; i>0; i--) {
// for(int j=0; j<i; j++) {
// if(arr[j]>arr[j+1]) {
// swap(arr,j,j+1);
// }
// }
// }
for (int i = 0; i < arr.length - 1; i++) {
for (int j = 0; j < arr.length - 1 - i; j++) {
if (arr[j] > arr[j + 1]) {
swap(arr, j, j + 1);
}
}
}
}
public static void main(String[] args) {
int testTime = 500000;// 测试次数,50万次
int maxSize = 100;// 数组的规模不大于100
int maxValue = 100;// 数组中每个值的范围,-100~+100
boolean succeed = true;
for (int i = 0; i < testTime; i++) {
int[] arr1 = generateRandomArray(maxSize, maxValue);
// 创建一个数组,长度随机,值也随机
int[] arr2 = copyArray(arr1);
bubbleSort(arr1);// (此处放自己写的排序算法)(arr1);
comparator(arr2);// 用系统提供的排序,来排arr2
// 排完序后,比较arr1和arr2的每个位置的值都是不是一样
if (isEqual(arr1, arr2) == false) {
// 若值不一样,则该次测试失败
succeed = false;
printArray(arr1);// 打印arr1排成了什么样
printArray(arr2);// 打印arr2排成了什么样
break;// 跳出循环
}
}
System.out.println(succeed == true ? "完全正确!" : "有错误");
}
}
测试结果:
2、直接插入排序
package 苟熊岭熊哒;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Arrays;
//直接插入排序
public class InsertSort {
public static void swap(int[] arr, int i, int j) {
int tmp = arr[i];
arr[i] = arr[j];
arr[j] = tmp;
}
// 直接插入排序
public static void insertSort(int[] arr) {
if (arr == null || arr.length < 2) {
return;
}
for (int i = 0; i < arr.length - 1; i++) {
for (int j = i + 1; (j > 0) && (arr[j] < arr[j - 1]); j--) {
swap(arr, j, j - 1);
}
}
}
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
System.out.println("请输入元素个数:");
int n = Integer.parseInt(br.readLine());
int[] arr = new int[n];
System.out.println("请输入元素内容(每个元素之间用空格分隔):");
String[] line = br.readLine().split(" ");
for (int i = 0; i < line.length; i++) {
arr[i] = Integer.parseInt(line[i]);
}
insertSort(arr);// 直接插入排序
System.out.println("排序后:" + Arrays.toString(arr));
}
}
输出结果:
对数器测试
package 苟熊岭熊哒;
import java.util.Arrays;
//直接插入排序
public class InsertSort {
// 用系统提供的方法进行排序
public static void comparator(int[] arr) {
Arrays.sort(arr);
}
// 生成一个随机数组
public static int[] generateRandomArray(int maxSize, int maxValue) {
// Math.random() -> 随机在[0,1)范围内返回一个double类型的数(等概率)
// Math.random()*A -> 随机在[0,A)范围内返回一个double类型的数(等概率)
// (int)(Math.random()*A) -> 随机在[0,A-1]范围内返回一个int类型的数(等概率)
int[] arr = new int[(int) ((maxSize + 1) * Math.random())];
for (int i = 0; i < arr.length; i++) {
arr[i] = (int) ((maxValue + 1) * Math.random()) - (int) ((maxValue + 1) * Math.random());
}
return arr;
}
// 拷贝数组
public static int[] copyArray(int[] arr) {
if (arr == null) {
return null;
}
int[] res = new int[arr.length];
for (int i = 0; i < arr.length; i++) {
res[i] = arr[i];
}
return res;
}
// 判断arr1和arr2中的每个值是否相等
public static boolean isEqual(int[] arr1, int[] arr2) {
int i = 0;
while (i < arr1.length) {
if (arr1[i] == arr2[i]) {
i++;
} else {
return false;
}
}
return true;
}
// 打印数组
public static void printArray(int[] arr) {
for (int a : arr) {
System.out.print(a + " ");
}
System.out.println();
}
// test
public static void swap(int[] arr, int i, int j) {
int tmp = arr[i];
arr[i] = arr[j];
arr[j] = tmp;
}
public static void insertSort(int[] arr) {
if (arr == null || arr.length < 2) {
return;
}
for (int i = 0; i < arr.length - 1; i++) {
for (int j = i + 1; (j > 0) && (arr[j] < arr[j - 1]); j--) {
swap(arr, j, j - 1);
}
}
}
public static void main(String[] args) {
int testTime = 500000;// 测试次数,50万次
int maxSize = 100;// 数组的规模不大于100
int maxValue = 100;// 数组中每个值的范围,-100~+100
boolean succeed = true;
for (int i = 0; i < testTime; i++) {
int[] arr1 = generateRandomArray(maxSize, maxValue);
// 创建一个数组,长度随机,值也随机
int[] arr2 = copyArray(arr1);
insertSort(arr1);// (此处放自己写的排序算法)(arr1);
comparator(arr2);// 用系统提供的排序,来排arr2
// 排完序后,比较arr1和arr2的每个位置的值都是不是一样
if (isEqual(arr1, arr2) == false) {
// 若值不一样,则该次测试失败
succeed = false;
printArray(arr1);// 打印arr1排成了什么样
printArray(arr2);// 打印arr2排成了什么样
break;// 跳出循环
}
}
System.out.println(succeed == true ? "完全正确!" : "有错误");
}
}
测试结果:
3、选择排序
package 苟熊岭熊哒;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Arrays;
//选择排序
public class SelectSort {
public static void swap(int[] arr, int i, int j) {
int tmp = arr[i];
arr[i] = arr[j];S
arr[j] = tmp;
}
// 选择排序
public static void selectSort(int[] arr) {
if (arr == null || arr.length < 2) {
return;
}
int min = 0;
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;
}
}
swap(arr, i, min);
}
}
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
System.out.println("请输入元素个数:");
int n = Integer.parseInt(br.readLine());
int[] arr = new int[n];
System.out.println("请输入元素内容(每个元素之间用空格分隔):");
String[] line = br.readLine().split(" ");
for (int i = 0; i < line.length; i++) {
arr[i] = Integer.parseInt(line[i]);
}
selectSort(arr);// 选择排序
System.out.println("排序后:" + Arrays.toString(arr));
}
}
输出结果:
对数器测试
package 苟熊岭熊哒;
import java.util.Arrays;
//选择排序
public class SelectSort {
// 用系统提供的方法进行排序
public static void comparator(int[] arr) {
Arrays.sort(arr);
}
// 生成一个随机数组
public static int[] generateRandomArray(int maxSize, int maxValue) {
// Math.random() -> 随机在[0,1)范围内返回一个double类型的数(等概率)
// Math.random()*A -> 随机在[0,A)范围内返回一个double类型的数(等概率)
// (int)(Math.random()*A) -> 随机在[0,A-1]范围内返回一个int类型的数(等概率)
int[] arr = new int[(int) ((maxSize + 1) * Math.random())];
for (int i = 0; i < arr.length; i++) {
arr[i] = (int) ((maxValue + 1) * Math.random()) - (int) ((maxValue + 1) * Math.random());
}
return arr;
}
// 拷贝数组
public static int[] copyArray(int[] arr) {
if (arr == null) {
return null;
}
int[] res = new int[arr.length];
for (int i = 0; i < arr.length; i++) {
res[i] = arr[i];
}
return res;
}
// 判断arr1和arr2中的每个值是否相等
public static boolean isEqual(int[] arr1, int[] arr2) {
int i = 0;
while (i < arr1.length) {
if (arr1[i] == arr2[i]) {
i++;
} else {
return false;
}
}
return true;
}
// 打印数组
public static void printArray(int[] arr) {
for (int a : arr) {
System.out.print(a + " ");
}
System.out.println();
}
// test
public static void swap(int[] arr, int i, int j) {
int tmp = arr[i];
arr[i] = arr[j];
arr[j] = tmp;
}
public static void selectSort(int[] arr) {
if (arr == null || arr.length < 2) {
return;
}
for (int i = 0; i < arr.length; i++) {
int min = i;
for (int j = i + 1; j < arr.length; j++) {
if (arr[j] < arr[min]) {
min = j;
}
}
swap(arr, i, min);
}
}
public static void main(String[] args) {
int testTime = 500000;// 测试次数,50万次
int maxSize = 100;// 数组的规模不大于100
int maxValue = 100;// 数组中每个值的范围,-100~+100
boolean succeed = true;
for (int i = 0; i < testTime; i++) {
int[] arr1 = generateRandomArray(maxSize, maxValue);
// 创建一个数组,长度随机,值也随机
int[] arr2 = copyArray(arr1);
selectSort(arr1);// (此处放自己写的排序算法)(arr1);
comparator(arr2);// 用系统提供的排序,来排arr2
// 排完序后,比较arr1和arr2的每个位置的值都是不是一样
if (isEqual(arr1, arr2) == false) {
// 若值不一样,则该次测试失败
succeed = false;
printArray(arr1);// 打印arr1排成了什么样
printArray(arr2);// 打印arr2排成了什么样
break;// 跳出循环
}
}
System.out.println(succeed == true ? "完全正确!" : "有错误");
}
}
测试结果:
4、归并排序
package 苟熊岭熊哒;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Arrays;
//归并排序
public class MergeSort {
public static void swap(int[] arr, int i, int j) {
int tmp = arr[i];
arr[i] = arr[j];
arr[j] = tmp;
}
// 归并排序--归并
private static void merge(int[] arr, int left, int mid, int right) {
// (right-left)+1:传过来的数组内的元素个数
int[] tmp = new int[(right - left) + 1];
int p = 0;// 临时数组tmp的下标
int p1 = left;// 左半边组的初始下标
int p2 = mid + 1;// 右半边组的初始下标
// 归并
while (p1 <= mid && p2 <= right) {
tmp[p++] = arr[p1] <= arr[p2] ? arr[p1++] : arr[p2++];
// 如果p1指向的数小于等于p2指向的数 (默认规定) ,则将p1指向的数拷入tmp数组中
// 反之则将p2指向的数拷入tmp数组中
}
// 当右边的组已经排完后,将左边组剩余的所有数直接拷到tmp数组中
while (p1 <= mid) {
tmp[p++] = arr[p1++];
}
// 当左边的组已经排完后,将右边组剩余的所有数直接拷到tmp数组中
while (p2 <= right) {
tmp[p++] = arr[p2++];
}
// 拷贝数组
for (int i = 0; i < tmp.length; i++) {
// 注意:arr数组是从i+left开始的
arr[i + left] = tmp[i];
}
}
// 归并排序--分组
private static void process(int[] arr, int left, int right) {
if (left == right) {
// 当left==right,说明已经分到只有一个数了,故直接返回
return;
}
int mid = left + ((right - left) >> 1);
process(arr, left, mid);// 分组--左半边
process(arr, mid + 1, right);// 分组--右半边
merge(arr, left, mid, right);// 归并
}
// 归并排序
public static void mergeSort(int[] arr) {
if (arr == null || arr.length < 2) {
return;
}
int left = 0;
int right = arr.length - 1;
process(arr, left, right);
}
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
System.out.println("请输入元素个数:");
int n = Integer.parseInt(br.readLine());
int[] arr = new int[n];
System.out.println("请输入元素内容(每个元素之间用空格分隔):");
String[] line = br.readLine().split(" ");
for (int i = 0; i < line.length; i++) {
arr[i] = Integer.parseInt(line[i]);
}
mergeSort(arr);// 归并排序
System.out.println("排序后:" + Arrays.toString(arr));
}
}
输出结果:
对数器测试
package 苟熊岭熊哒;
import java.util.Arrays;
//归并排序
public class MergeSort {
// 用系统提供的方法进行排序
public static void comparator(int[] arr) {
Arrays.sort(arr);
}
// 生成一个随机数组
public static int[] generateRandomArray(int maxSize, int maxValue) {
// Math.random() -> 随机在[0,1)范围内返回一个double类型的数(等概率)
// Math.random()*A -> 随机在[0,A)范围内返回一个double类型的数(等概率)
// (int)(Math.random()*A) -> 随机在[0,A-1]范围内返回一个int类型的数(等概率)
int[] arr = new int[(int) ((maxSize + 1) * Math.random())];
for (int i = 0; i < arr.length; i++) {
arr[i] = (int) ((maxValue + 1) * Math.random()) - (int) ((maxValue + 1) * Math.random());
}
return arr;
}
// 拷贝数组
public static int[] copyArray(int[] arr) {
if (arr == null) {
return null;
}
int[] res = new int[arr.length];
for (int i = 0; i < arr.length; i++) {
res[i] = arr[i];
}
return res;
}
// 判断arr1和arr2中的每个值是否相等
public static boolean isEqual(int[] arr1, int[] arr2) {
int i = 0;
while (i < arr1.length) {
if (arr1[i] == arr2[i]) {
i++;
} else {
return false;
}
}
return true;
}
// 打印数组
public static void printArray(int[] arr) {
for (int a : arr) {
System.out.print(a + " ");
}
System.out.println();
}
// test
private static void mergeSort(int[] arr) {
if (arr == null || arr.length < 2) {
return;
}
int left = 0;
int right = arr.length - 1;
process(arr, left, right);
}
// 归并排序--分组
private static void process(int[] arr, int left, int right) {
if (left == right) {
// 当left==right,说明已经分到只有一个数了,故直接返回
return;
}
int mid = left + ((right - left) >> 1);
process(arr, left, mid);// 分组--左半边
process(arr, mid + 1, right);// 分组--右半边
merge(arr, left, mid, right);// 归并
}
// 归并排序--归并
private static void merge(int[] arr, int left, int mid, int right) {
// (right-left)+1:传过来的数组内的元素个数
int[] tmp = new int[(right - left) + 1];
int p = 0;// 临时数组tmp的下标
int p1 = left;// 左半边组的初始下标
int p2 = mid + 1;// 右半边组的初始下标
// 归并
while (p1 <= mid && p2 <= right) {
tmp[p++] = arr[p1] <= arr[p2] ? arr[p1++] : arr[p2++];
// 如果p1指向的数小于等于p2指向的数 (默认规定) ,则将p1指向的数拷入tmp数组中
// 反之则将p2指向的数拷入tmp数组中
}
// 当右边的组已经排完后,将左边组剩余的所有数直接拷到tmp数组中
while (p1 <= mid) {
tmp[p++] = arr[p1++];
}
// 当左边的组已经排完后,将右边组剩余的所有数直接拷到tmp数组中
while (p2 <= right) {
tmp[p++] = arr[p2++];
}
// 拷贝数组
for (int i = 0; i < tmp.length; i++) {
// 注意:arr数组是从i+left开始的
arr[i + left] = tmp[i];
}
}
public static void main(String[] args) {
int testTime = 500000;// 测试次数,50万次
int maxSize = 100;// 数组的规模不大于100
int maxValue = 100;// 数组中每个值的范围,-100~+100
boolean succeed = true;
for (int i = 0; i < testTime; i++) {
int[] arr1 = generateRandomArray(maxSize, maxValue);
// 创建一个数组,长度随机,值也随机
int[] arr2 = copyArray(arr1);
mergeSort(arr1);// (此处放自己写的排序算法)(arr1);
comparator(arr2);// 用系统提供的排序,来排arr2
// 排完序后,比较arr1和arr2的每个位置的值都是不是一样
if (isEqual(arr1, arr2) == false) {
// 若值不一样,则该次测试失败
succeed = false;
printArray(arr1);// 打印arr1排成了什么样
printArray(arr2);// 打印arr2排成了什么样
break;// 跳出循环
}
}
System.out.println(succeed == true ? "完全正确!" : "有错误");
}
}
测试结果:
5、堆排序
package 苟熊岭熊哒;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Arrays;
//堆排序
public class HeapSort {
public static void swap(int[] arr, int i, int j) {
int tmp = arr[i];
arr[i] = arr[j];
arr[j] = tmp;
}
// 下沉--heapify
public static void heapify(int[] nums, int index, int heapSize) {
// index开始等于0,表示从0开始向下沉
// index也表示父节点的索引
int left = index * 2 + 1;// 左孩子的下标
while (left < heapSize) {// 表示下方还有孩子
// 左孩子和右孩子相比,谁的值大,谁把下标给largest变量
// 若left+1>=heapSize,表示没有右孩子
int largest = left + 1 < heapSize && nums[left + 1] > nums[left] ? left + 1 : left;
// 父亲和较大的孩子之间,谁的值大,谁把下标给largest变量
largest = nums[largest] > nums[index] ? largest : index;
if (largest == index) {
// 如果父节点最大,则下沉过程结束
break;
}
// 若上述判断条件不成立,则交换父节点和较大孩子的值
swap(nums, largest, index);
index = largest;// 父节点继续下沉
left = index * 2 + 1;// 表示左孩子的索引
}
}
// 上浮--heapInsert
public static void heapInsert(int[] nums, int index) {
while (nums[index] > nums[(index - 1) / 2]) {
swap(nums, index, (index - 1) / 2);
index = (index - 1) / 2;
}
}
// 堆排序
public static void heapSort(int[] nums) {
if (nums == null || nums.length < 2) {
return;
}
// 先用上浮算法,构建堆结构
// O(N*logN)
for (int i = 0; i < nums.length; i++) { // O(N)
// 一个一个上浮
heapInsert(nums, i); // O(logN)
}
// 使用下沉算法,进行堆排序
int heapSize = nums.length;
swap(nums, 0, --heapSize);
while (heapSize > 0) { // O(N)
heapify(nums, 0, heapSize); // O(logN)
swap(nums, 0, --heapSize); // O(1)
}
}
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
System.out.println("请输入元素个数:");
int n = Integer.parseInt(br.readLine());
int[] arr = new int[n];
System.out.println("请输入元素内容(每个元素之间用空格分隔):");
String[] line = br.readLine().split(" ");
for (int i = 0; i < line.length; i++) {
arr[i] = Integer.parseInt(line[i]);
}
heapSort(arr);// 堆排序
System.out.println("排序后:" + Arrays.toString(arr));
}
}
输出结果:
对数器测试
package 苟熊岭熊哒;
import java.util.Arrays;
//堆排序
public class HeapSort {
// 用系统提供的方法进行排序
public static void comparator(int[] arr) {
Arrays.sort(arr);
}
// 生成一个随机数组
public static int[] generateRandomArray(int maxSize, int maxValue) {
// Math.random() -> 随机在[0,1)范围内返回一个double类型的数(等概率)
// Math.random()*A -> 随机在[0,A)范围内返回一个double类型的数(等概率)
// (int)(Math.random()*A) -> 随机在[0,A-1]范围内返回一个int类型的数(等概率)
int[] arr = new int[(int) ((maxSize + 1) * Math.random())];
for (int i = 0; i < arr.length; i++) {
arr[i] = (int) ((maxValue + 1) * Math.random()) - (int) ((maxValue + 1) * Math.random());
}
return arr;
}
// 拷贝数组
public static int[] copyArray(int[] arr) {
if (arr == null) {
return null;
}
int[] res = new int[arr.length];
for (int i = 0; i < arr.length; i++) {
res[i] = arr[i];
}
return res;
}
// 判断arr1和arr2中的每个值是否相等
public static boolean isEqual(int[] arr1, int[] arr2) {
int i = 0;
while (i < arr1.length) {
if (arr1[i] == arr2[i]) {
i++;
} else {
return false;
}
}
return true;
}
// 打印数组
public static void printArray(int[] arr) {
for (int a : arr) {
System.out.print(a + " ");
}
System.out.println();
}
// test
// 交换
public static void swap(int[] nums, int i, int j) {
int tmp = nums[i];
nums[i] = nums[j];
nums[j] = tmp;
}
// 下沉--heapify
public static void heapify(int[] nums, int index, int heapSize) {
// index开始等于0,表示从0开始向下沉
// index也表示父节点的索引
int left = index * 2 + 1;// 左孩子的下标
while (left < heapSize) {// 表示下方还有孩子
// 左孩子和右孩子相比,谁的值大,谁把下标给largest变量
// 若left+1>=heapSize,表示没有右孩子
int largest = left + 1 < heapSize && nums[left + 1] > nums[left] ? left + 1 : left;
// 父亲和较大的孩子之间,谁的值大,谁把下标给largest变量
largest = nums[largest] > nums[index] ? largest : index;
if (largest == index) {
// 如果父节点最大,则下沉过程结束
break;
}
// 若上述判断条件不成立,则交换父节点和较大孩子的值
swap(nums, largest, index);
index = largest;// 父节点继续下沉
left = index * 2 + 1;// 表示左孩子的索引
}
}
// 上浮--heapInsert
public static void heapInsert(int[] nums, int index) {
while (nums[index] > nums[(index - 1) / 2]) {
swap(nums, index, (index - 1) / 2);
index = (index - 1) / 2;
}
}
// 堆排序
public static void heapSort(int[] nums) {
if (nums == null || nums.length < 2) {
return;
}
// 先用上浮算法,构建堆结构
// O(N*logN)
for (int i = 0; i < nums.length; i++) { // O(N)
// 一个一个上浮
heapInsert(nums, i); // O(logN)
}
// 使用下沉算法,进行堆排序
int heapSize = nums.length;
swap(nums, 0, --heapSize);
while (heapSize > 0) { // O(N)
heapify(nums, 0, heapSize); // O(logN)
swap(nums, 0, --heapSize); // O(1)
}
}
public static void main(String[] args) {
int testTime = 500000;// 测试次数,50万次
int maxSize = 100;// 数组的规模不大于100
int maxValue = 100;// 数组中每个值的范围,-100~+100
boolean succeed = true;
for (int i = 0; i < testTime; i++) {
int[] arr1 = generateRandomArray(maxSize, maxValue);
// 创建一个数组,长度随机,值也随机
int[] arr2 = copyArray(arr1);
heapSort(arr1);// (此处放自己写的排序算法)(arr1);
comparator(arr2);// 用系统提供的排序,来排arr2
// 排完序后,比较arr1和arr2的每个位置的值都是不是一样
if (isEqual(arr1, arr2) == false) {
// 若值不一样,则该次测试失败
succeed = false;
printArray(arr1);// 打印arr1排成了什么样
printArray(arr2);// 打印arr2排成了什么样
break;// 跳出循环
}
}
System.out.println(succeed == true ? "完全正确!" : "有错误");
}
}
测试结果:
6、快速排序
package 苟熊岭熊哒;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Arrays;
//快速排序
public class QuickSort {
public static void swap(int[] arr, int i, int j) {
int tmp = arr[i];
arr[i] = arr[j];
arr[j] = tmp;
}
public static int[] partition(int[] arr, int L, int R) {
int less = L - 1;// 小于区的右边界
int more = R;// 大于区的左边界
while (L < more) {
// L表示当前数的位置,arr[R]表示划分值
if (arr[L] < arr[R]) {
swap(arr, ++less, L++);
// 如果当前数小于划分值
// 则当前数和小于区有边界后面一个元素做交换
// 并将小于区向后扩大1位
// less++;
// L++;
} else if (arr[L] > arr[R]) {
swap(arr, --more, L);
} else {
L++;
}
}
swap(arr, more, R);
return new int[] { less + 1, more };
// 返回等于区所处的范围
}
public static void process(int[] arr, int L, int R) {
if (L < R) {
swap(arr, L + (int) (Math.random() * (R - L + 1)), R);
// 随机在数组中找一个元素和末尾的值做交换
int[] p = partition(arr, L, R);
process(arr, L, p[0] - 1);// 小于区
process(arr, p[1] + 1, R);// 大于区
}
}
// 快速排序
public static void quickSort(int[] arr) {
if (arr == null || arr.length < 2) {
return;
}
int L = 0;
int R = arr.length - 1;
process(arr, L, R);// 开始执行
}
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
System.out.println("请输入元素个数:");
int n = Integer.parseInt(br.readLine());
int[] arr = new int[n];
System.out.println("请输入元素内容(每个元素之间用空格分隔):");
String[] line = br.readLine().split(" ");
for (int i = 0; i < line.length; i++) {
arr[i] = Integer.parseInt(line[i]);
}
quickSort(arr);// 快速排序
System.out.println("排序后:" + Arrays.toString(arr));
}
}
输出结果:
对数器测试
package 苟熊岭熊哒;
import java.util.Arrays;
//快速排序
public class QuickSort {
// 用系统提供的方法进行排序
public static void comparator(int[] arr) {
Arrays.sort(arr);
}
// 生成一个随机数组
public static int[] generateRandomArray(int maxSize, int maxValue) {
// Math.random() -> 随机在[0,1)范围内返回一个double类型的数(等概率)
// Math.random()*A -> 随机在[0,A)范围内返回一个double类型的数(等概率)
// (int)(Math.random()*A) -> 随机在[0,A-1]范围内返回一个int类型的数(等概率)
int[] arr = new int[(int) ((maxSize + 1) * Math.random())];
for (int i = 0; i < arr.length; i++) {
arr[i] = (int) ((maxValue + 1) * Math.random()) - (int) ((maxValue + 1) * Math.random());
}
return arr;
}
// 拷贝数组
public static int[] copyArray(int[] arr) {
if (arr == null) {
return null;
}
int[] res = new int[arr.length];
for (int i = 0; i < arr.length; i++) {
res[i] = arr[i];
}
return res;
}
// 判断arr1和arr2中的每个值是否相等
public static boolean isEqual(int[] arr1, int[] arr2) {
int i = 0;
while (i < arr1.length) {
if (arr1[i] == arr2[i]) {
i++;
} else {
return false;
}
}
return true;
}
// 打印数组
public static void printArray(int[] arr) {
for (int a : arr) {
System.out.print(a + " ");
}
System.out.println();
}
// test
public static void swap(int[] arr, int i, int j) {
int tmp = arr[i];
arr[i] = arr[j];
arr[j] = tmp;
}
public static int[] partition(int[] arr, int L, int R) {
int less = L - 1;// 小于区的右边界
int more = R;// 大于区的左边界
while (L < more) {
// L表示当前数的位置,arr[R]表示划分值
if (arr[L] < arr[R]) {
swap(arr, ++less, L++);
// 如果当前数小于划分值
// 则当前数和小于区有边界后面一个元素做交换
// 并将小于区向后扩大1位
// less++;
// L++;
} else if (arr[L] > arr[R]) {
swap(arr, --more, L);
} else {
L++;
}
}
swap(arr, more, R);
return new int[] { less + 1, more };
// 返回等于区所处的范围
}
public static void process(int[] arr, int L, int R) {
if (L < R) {
swap(arr, L + (int) (Math.random() * (R - L + 1)), R);
// 随机在数组中找一个元素和末尾的值做交换
int[] p = partition(arr, L, R);
process(arr, L, p[0] - 1);// 小于区
process(arr, p[1] + 1, R);// 大于区
}
}
public static void quickSort(int[] arr) {
if (arr == null || arr.length < 2) {
return;
}
int L = 0;
int R = arr.length - 1;
process(arr, L, R);// 开始执行
}
public static void main(String[] args) {
int testTime = 500000;// 测试次数,50万次
int maxSize = 100;// 数组的规模不大于100
int maxValue = 100;// 数组中每个值的范围,-100~+100
boolean succeed = true;
for (int i = 0; i < testTime; i++) {
int[] arr1 = generateRandomArray(maxSize, maxValue);
// 创建一个数组,长度随机,值也随机
int[] arr2 = copyArray(arr1);
// 拷贝arr1中的值和长度
quickSort(arr1);// 快速排序
comparator(arr2);// 用系统提供的排序,来排arr2
// 排完序后,比较arr1和arr2的每个位置的值都是不是一样
if (isEqual(arr1, arr2) == false) {
// 若值不一样,则该次测试失败
succeed = false;
printArray(arr1);// 打印arr1排成了什么样
printArray(arr2);// 打印arr2排成了什么样
break;// 跳出循环
}
}
System.out.println(succeed == true ? "完全正确!" : "有错误");
}
}
测试结果:
7、*计数排序(不含对数器)
应用范围很有限,如果数据有变动,算法很可能要大规模重写
package 牛客算法基础入门;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Arrays;
//计数排序
public class CountSort {
public static void countSort(int[] arr) {
if (arr == null | arr.length < 2) {
return;
}
int max = Integer.MIN_VALUE;
// 找出最大值
for (int i = 0; i < arr.length; i++) {
max = Math.max(max, arr[i]);
}
// 准备一个 max+1 个桶
int[] bucket = new int[max + 1];
// 计数
for (int i = 0; i < arr.length; i++) {
bucket[arr[i]]++;
}
int i = 0;
// 倒出
for (int j = 0; j < bucket.length; j++) {
while (bucket[j]-- > 0) {
arr[i++] = j;
}
}
}
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
System.out.println("请输入元素个数:");
int n = Integer.parseInt(br.readLine());
int[] arr = new int[n];
System.out.println("请输入元素内容(每个元素之间用空格分隔):");
String[] line = br.readLine().split(" ");
for (int i = 0; i < line.length; i++) {
arr[i] = Integer.parseInt(line[i]);
}
countSort(arr);// 计数排序
System.out.println("排序后:" + Arrays.toString(arr));
}
}
输出结果:
8、*基数排序(不含对数器)
只能处理非负值
package 牛客算法基础入门;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Arrays;
//基数排序
public class RadixSort {
public static int maxbits(int[] arr) {
int max = Integer.MIN_VALUE;
for (int i = 0; i < arr.length; i++) {
max = Math.max(max, arr[i]);
}
int res = 0;
while (max != 0) {
res++;
max /= 10;
}
return res;
}
public static int getDigit(int x, int d) {
return ((x / ((int) Math.pow(10, d - 1))) % 10);
}
public static void radixSort(int[] arr, int L, int R, int digit) {
// digit:最大的数有几个十进制位
final int radix = 10;// 表示10进制
int i = 0, j = 0;
// 有多少个数准备多少个辅助空间
int[] bucket = new int[R - L + 1];
for (int d = 1; d <= digit; d++) {// 有多少位就进出几次
int[] count = new int[radix];
// 统计数组,范围始终是[0~9]
for (i = L; i <= R; i++) {
j = getDigit(arr[i], d);// 取出个位数字
count[j]++;
// 此时的count数组,表示个位数字等于其索引值的数有几个
}
for (i = 1; i < radix; i++) {
count[i] = count[i] + count[i - 1];
// 此时的count数组,表示个位数字<=其索引值的数有几个
}
for (i = R; i >= L; i--) {
j = getDigit(arr[i], d);// 取出个位数字
bucket[count[j] - 1] = arr[i];
count[j]--;
}
for (i = L, j = 0; i <= R; i++, j++) {
arr[i] = bucket[j];
// 将bucket的元素拷贝到原数组
}
}
}
public static void radixSort(int[] arr) {
if (arr == null || arr.length < 2) {
return;
}
radixSort(arr, 0, arr.length - 1, maxbits(arr));
}
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
System.out.println("请输入元素个数:");
int n = Integer.parseInt(br.readLine());
int[] arr = new int[n];
System.out.println("请输入元素内容(每个元素之间用空格分隔):");
String[] line = br.readLine().split(" ");
for (int i = 0; i < line.length; i++) {
arr[i] = Integer.parseInt(line[i]);
}
radixSort(arr);// 基数排序
System.out.println("排序后:" + Arrays.toString(arr));
}
}
输出结果:
各排序的性能统计
总结:时间选快排,空间选堆排,稳定选归并。
常见排序的介绍到这里就结束了,如果你觉得本篇文章对你多少有些帮助,可以点个赞或者收藏一波支持一下哦,欢迎各位大佬批评指正,咱们下次再见!