目录
1.冒泡排序 (Bubble Sort)
这是最简单的排序算法之一。它通过重复地交换相邻的两个元素,直到整个数组有序。时间复杂度为O(n^2)。
//冒泡排序
public class BubbleSort {
public static void main(String[] args) {
int[] arr= {25,3,17,61,34,22,5,13};
sort(arr);
System.out.println(Arrays.toString(arr));
}
public static void sort(int[] arr) {
for(int j=0;j<arr.length;j++) {
for(int i=0;i<arr.length-1;i++) {
if(arr[i]>arr[i+1]) {
int temp;
temp=arr[i];
arr[i]=arr[i+1];
arr[i+1]=temp;
}
}
}
}
}
2.选择排序 (Select Sort)
它首先找到数组中的最小元素,然后将其与数组的第一个元素交换位置。接着,它在剩下的元素中找到最小的元素,与数组的第二个元素交换位置,依此类推。时间复杂度为O(n^2)。
//选择排序
public class SelectSort {
public static void main(String[] args) {
int[] arr= {25,3,17,61,34,22,5,13};
sort(arr);
System.out.println(Arrays.toString(arr));
}
public static void sort(int[] arr) {
for(int j=0;j<arr.length;j++) {
int min=arr[j];//定义一个变量存放最小值
int minIndex=j;//记录最小值的下标
for(int i=j;i<arr.length;i++) {
if(arr[i]<min) {
min=arr[i];
minIndex=i;
}
}
//min存放的真正的最小值
//最小值和待排序数组中的第一个进行交换
arr[minIndex]=arr[j];
arr[j]=min;
}
}
}
3.插入排序 (Insertion Sort)
通过构建有序序列,对于未排序的数据,在已排序的序列中从后向前扫描,找到相应位置并插入。时间复杂度为O(n^2)。
//插入排序
public class InsertSort {
public static void main(String[] args) {
int[] number=new int[10];
int sum=0;
int a=0;
for(int j=0;j<200;j++) {
for(int i=0;i<10;i++) {
number[i]=(int)(Math.random()*1000);
//System.out.print(number[i]+" ");
sum=sum+number[i];
}
//System.out.println();
//System.out.println(sum);
a=sum/10;
System.out.print(a+" ");
sum=0;
sort(number);
//System.out.println(Arrays.toString(number));
}/*
int[] arr= {25,3,17,61,34,22,5,13};
sort(arr);
System.out.println(Arrays.toString(arr));*/
}
public static void sort(int[] arr) {
for(int i=1;i<arr.length;i++) {
for(int j=i-1;j>=0;j--) {
if(arr[j+1]<arr[j]) {
int temp;
temp=arr[j];
arr[j]=arr[j+1];
arr[j+1]=temp;
}
else {
break;
}
}
}
}
}
4.希尔排序 (Shell Sort)
希尔排序是插入排序的一种更高效的改进版本。它根据数组的大小选择合适的增量序列,使用插入排序算法对数组进行逐步有序化,直到整个数组有序。时间复杂度为O(n^(1.25))。
//希尔排序
public class ShellSort {
public static void main(String[] args) {
int[] arr= {25,3,17,61,34,22,5,13};
sort(arr);
System.out.println(Arrays.toString(arr));
}
public static void sort(int[] arr) {
//控制步长
for(int grp=arr.length/2;grp>0;grp=grp/2) {
//i游标控制要进行排序的数据
for(int i=grp;i<arr.length;i++) {
for(int j=i-grp;j>=0;j=j-grp) {
//j和j+步长 进行对比交换
if(arr[j]>arr[j+grp]) {
int temp=arr[j];
arr[j]=arr[j+grp];
arr[j+grp]=temp;
}else {
break;
}
}
}
}
}
}
5.归并排序 (Merge Sort)
归并排序采用分治策略的高效排序算法。它将待排序数组递归地划分为更小的子数组,对每个子数组进行排序,然后再将有序的子数组合并成一个完整的有序数组。时间复杂度为O(n log n)。
//归并排序
public class MergeSort {
public static void main(String[] args) {
int[] arr = {25,3,17,61,34,22,5,13};
mergeSort(arr, 0, arr.length-1);
System.out.println(Arrays.toString(arr));
}
//拆分
public static void mergeSort(int[] arr,int left,int right) {
//递归出口
if(left>=right) {
return;
}
int mid =(left + right)/2;
//向左递归
mergeSort(arr,left,mid);
//向右递归
mergeSort(arr,mid+1,right);
//合并
merge(arr, left, mid, right);
}
//合并
public static void merge(int[] arr,int left,int mid,int right) {
//定义第一个数组的开始
int s1 = left;
//定义第二个数组的开始
int s2 = mid+1;
//定义临时数组
int[] temp = new int[right - left+1];
//定义临时数组的下标
int index =0;
//判断数组大小,放入到临时数组里
while(s1<=mid &&s2<=right) {
if(arr[s1]<arr[s2]) {
temp[index] = arr[s1];
s1++;
index++;
}else {
temp[index] = arr[s2];
s2++;
index++;
}
}
//判断s1是否还有数据,如果有,将其全部放入临时数组
while(s1<=mid) {
temp[index] = arr[s1];
s1++;
index++;
}
//判断s2是否还有数据,如果有,将其全部放入临时数组
while(s2<=right) {
temp[index] = arr[s2];
s2++;
index++;
}
//将临时数组当中的数据放回原数组
for(int j=0;j<temp.length;j++) {
arr[j+left] = temp[j];
}
}
}
6.快速排序 (Quick Sort)
快速排序也是一种采用分治策略的高效排序算法。它通过选择一个基准元素,将数组划分为两个子数组,其中一个子数组的所有元素都小于基准值,另一个子数组的所有元素都大于基准值。然后递归地对这两个子数组进行排序。它的平均时间复杂度为O(n log n)。
//快速排序
public class QuickSort {
public static void main(String[] args) {
int[] arr= {25,3,17,61,34,22,5,13};
sort(arr,0,arr.length-1);
System.out.println(Arrays.toString(arr));
}
public static void sort(int[] arr,int left,int right) {
if(left>=right) {
return;
}
//定义变量保存基准数
int base=arr[left];
//定义i游标,定义j游标
int i=left;
int j=right;
while(i!=j) {
//j从后往前寻找比基准数小的,如果找到比基准数小的值就停下
while(arr[j]>=base && i<j) {
j--;
}
//i从前往后寻找比基准数大的,如果找到比基准数大的值就停下
while(arr[i]<=base &&i<j) {
i++;
}
//i和j都停下,进行交换
int temp=arr[i];
arr[i]=arr[j];
arr[j]=temp;
}
//i和j相遇
arr[left]=arr[i];
arr[i]=base;
//排序基准数左边
sort(arr,left,i-1);
//排序基准数右边
sort(arr,i+1,right);
}
}
7.堆排序 (Heap Sort)
堆排序是一种基于 二叉堆 的比较高效的排序算法。它首先将数组构建成一个二叉堆,然后不断地从堆中取出最大元素,直到整个数组有序。时间复杂度为O(n log n)。
//堆排序
public class HeapSort {
public static void main(String[] args) {
int[] arr = {25,3,17,61,34,22,5,13};
//构建大顶堆
for(int p=arr.length-1;p>=0;p--) {
adjust(arr,p,arr.length);
}
//堆顶和堆底进行交换
for(int i = arr.length-1 ;i>=0;i--) {
int temp = arr[i];
arr[i] = arr[0];
arr[0] = temp;
adjust(arr,0,i);
}
System.out.println(Arrays.toString(arr));
}
public static void adjust(int[] arr,int parent,int length) {
int child=2*parent+1;//定义(左)孩子
while(child<length) {
//定义右孩子,找到左右孩子当中的最大值
int rchild=child+1;//rchild=2*parent+2;
//如果有右孩子且右孩子较大
if(rchild<length && arr[rchild]>arr[child]) {
child++;//child是左孩子,++后是右孩子
}
//父子结点对比,父节点小于子节点时交换
if(arr[parent]<arr[child]) {
//进行交换
int temp=arr[parent];
arr[parent]=arr[child];
arr[child]=temp;
//向下检查
parent=child;
child=2*child+1;
}else {
break;
}
}
}
}
8.基数排序 (Radix Sort)
它根据数字的每位数字进行排序。基数排序是通过将整数分割成不同的 位数 来排序的。时间复杂度为O(kn),其中k为数据的最大值的位数。
//基数排序
public class RadixSort {
public static void main(String[] args) {
int[] arr = {25,3,17,61,34,163,22,5,13,152};
sort(arr);
System.out.println(Arrays.toString(arr));
}
public static void sort(int[] arr) {
//找到数组中的最大值
int max = arr[0];
for(int i = 0;i<arr.length;i++) {
if(arr[i]>max) {
max = arr[i];
}
}
//得到最大值的位数(转换成字符串)
int maxLen = (max+"").length();
//定义桶
int[][] bucket = new int[10][arr.length];
//定义桶记录工具
int[] elementCount = new int[10];
int n = 1;
for(int h = 0;h<maxLen;h++) {
//遍历数组,放入数据
for(int i =0;i<arr.length;i++) {
int element = arr[i]/n%10;//element代表放到哪号桶
//记录桶纪录工具中的数据
int count = elementCount[element];
bucket[element][count] = arr[i];
//数据放入之后,桶纪录+1
elementCount[element]++;
}
//取出数据
//定义index游标用来遍历数组
int index = 0;
//遍历桶纪录,看一下桶内有多少数据
for(int k=0;k<elementCount.length;k++) {
if(elementCount[k]!=0) {
for(int l=0;l<elementCount[k];l++) {
arr[index] = bucket[k][l];
index++;
}
}
//清空桶纪录
elementCount[k]=0;
}
n = n*10;
}
}
}