选择排序
把所有的元素遍历一遍,找到最小,放在首位置。对剩下的继续排序,找到最小的,放在第二位,以此类推。
/**
* @author mino
* @date 2022/2/23 10:12 下午
* 选择排序
*/
public class SelectionSort {
public static void main(String[] args){
int[] arr = {5,3,6,1,9,4,8,0,7};
for(int i = 0;i < arr.length - 1;i++){//要保证后面还有一个数
int minPos = i;
for(int j = i+1;j<arr.length;j++){
// if(arr[j] < arr[minPos]){
// minPos = j;
// }
minPos = arr[j] < arr[minPos] ? j: minPos;//精简一点
}
System.out.println("minPos: " + arr[minPos]);
// int temp = arr[i];
// arr[i] = arr[minPos];
// arr[minPos] = temp;
swap(arr,i,minPos);
// swap(arr[i],arr[minPos]);//这样写,相当与没换,没传进去值
System.out.println("经过第" + i +"次循环后,数组第内容为");
// for(int k = 0;k < arr.length;k++){
// System.out.print(arr[k] + " ");
// }
print(arr);
}
}
static void print(int[] arr){
for(int i = 0;i < arr.length;i++){
System.out.print(arr[i]+" ");
}
}
static void swap(int[] arr,int a,int b){
int temp = arr[a];
arr[a] = arr[b];
arr[b] = temp;
}
static void swap(int a,int b){
int temp = a;
a = b;
b = temp;
}
}
冒泡排序
从首位开始两两比较,把大的数往后移,移到最后一位之后;再反复(在前N-1个数上重复此操作)。
核心在于寻找最小数,0至N-1上最小数与0位置上数交换,1至N-1上最小的数与1位置上数进行交换,……以此类推。 核心与冒泡排序类似,所以时间复杂度也为O(N^2)。
/**
* @author mino
* @date 2022/2/23 11:10 下午
* 冒泡排序
*/
public class BubbleSort {
public static void main(String[] args) {
int[] arr = {5, 3, 6, 1, 9, 4, 8, 0, 7};
sort(arr);
print(arr);
}
static void sort(int[] arr){
for(int i = arr.length-1;i > 0;i--){
findMax(arr,i);//先i=8,写出findMax验证无误,再去想外层循环
}
}
static void findMax(int[] arr,int n){//n=8
for(int i=0;i<n;i++){
if(arr[i] > arr[i+1]) swap(arr,i,i+1);
}
}
static void print(int[] arr){
for(int i = 0;i < arr.length;i++){
System.out.print(arr[i]+" ");
}
}
static void swap(int[] arr,int a,int b){
int temp = arr[a];
arr[a] = arr[b];
arr[b] = temp;
}
}
验证算法–对数器
1肉眼观察
2产生足够多随机样本
3用确定正确的算法计算样本结果
4对比被验证算法的结果
import java.util.Arrays;
import java.util.Random;
/**
* @author mino
* @date 2022/2/24 11:40 下午
*/
public class DataChecker {
static int[] generateRandomArray(){
Random r = new Random();
int[] arr = new int[10000];
for(int i = 0;i < arr.length;i++){
arr[i] = r.nextInt(10000);
}
return arr;
}
static void check(){
int[] arr = generateRandomArray();
int[] arr2 = new int[arr.length];//一定要拷贝一份
System.arraycopy(arr,0,arr2,0,arr.length);
Arrays.sort(arr);
SelectionSort.sort(arr2);
// BubbleSort.sort(arr2);
boolean same = true;
for(int i = 0;i < arr.length;i++){
if(arr[i] != arr2[i]) same = false;
}
System.out.println(same == true ? "right" : "wrong");
}
public static void main(String[] args) {
check();
}
}
插入排序
第一位和第二位数字比较,小的放前面,相当这两个数有序了,再排第三个数,比较看排着哪个位置。
核心思想类似于扑克牌排列,前1个,前2个,……前N个内部排列。
/**
* @author mino
* @date 2022/2/25 12:04 上午
*/
public class InsertionSort {
public static void main(String[] args) {
int[] arr = {5, 3, 6, 1, 9, 4, 8, 0, 7};
sort(arr);
print(arr);
}
static void sort(int[] arr){
for(int j =1;j < arr.length;j++)
for(int i=j;i >0;i--){
if(arr[i] < arr[i-1]) swap(arr,i,i-1);
}
}
static void print(int[] arr){
for(int i = 0;i < arr.length;i++){
System.out.print(arr[i]+" ");
}
}
static void swap(int[] arr,int a,int b){
int temp = arr[a];
arr[a] = arr[b];
arr[b] = temp;
}
}
希尔排序
插入排序的进阶版。
先按一定间隙对数组进行插入排序,减小间隙,直到间隙gap为1,完成排序。
/**
* @author mino
* @date 2022/2/25 12:17 上午
*/
public class ShellSort {
public static void main(String[] args) {
int[] arr = {5, 13, 6, 11, 4, 0, 8, 17, 7, 12, 1, 3, 2, 10, 15, 19};
sort(arr);
print(arr);
}
static void sort(int[] arr) {
int h = 1;
while(h <= arr.length/3){//大于1/3,则不行了,所以是小于等于
h = h*3 + 1;//数学家发明的序列作为间隔 Knuth序列 h=1 h=3*h+1
}
for(int gap = h ;gap > 0 ;gap =(gap-1)/3){//gap=4;gap=arr.length/2
for (int j = gap; j < arr.length; j++) {//这里j不是+gap,因为每个数都要按间隙去比较
for (int i = j; i > gap-1; i -= gap) {//因为下面要(i-gap),所以(i-gap)得存在,因此(i>gap-1)
if (arr[i] < arr[i - gap]) swap(arr, i, i - gap);
}
}
}
}
static void print(int[] arr){
for(int i = 0;i < arr.length;i++){
System.out.print(arr[i]+" ");
}
}
static void swap(int[] arr,int a,int b){
int temp = arr[a];
arr[a] = arr[b];
arr[b] = temp;
}
}