1.冒泡排序
public static int[] Bubble(int[] arr){
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]){
int temp=arr[j];
arr[j]=arr[j+1];
arr[j+1]=temp;
}
}
}
return arr;
}
时间复杂度:O(n^2);
空间复杂度:O(1);
稳定性:稳定
2.直接插入排序
//直接插入排序
public static int[] Selection(int[] arr){
for(int i=1;i<arr.length;i++){
for(int j=i;j>0;j--){
if(arr[j]<arr[j-1]){
int temp=arr[j];
arr[j]=arr[j-1];
arr[j-1]=temp;
}
}
}
return arr;
}
时间复杂度:O(n^2);
空间复杂度:O(1);
稳定性:稳定
3.选择排序
public static int[] SelectionSort(int[] arr){
for(int i=0;i<arr.length;i++){
for(int j=i+1;j<arr.length;j++){
if(arr[i]>arr[j]){
int temp=arr[i];
arr[i]=arr[j];
arr[j]=temp;
}
}
}
return arr;
}
时间复杂度:O(n^2);
空间复杂度:O(1);
稳定性:不稳定
4.希尔排序
//希尔排序
public static int[] ShellSort(int[] arr){
int gap=1;
while(gap<arr.length/3){
gap=gap*3+1;
}
for(int h=gap;h>0;h=(h-1)/3){
for(int i=h;i<arr.length;i++){
for(int j=i;j>h-1;j=j-h){
if(arr[j]<arr[j-h]){
int temp=arr[j];
arr[j]=arr[j-h];
arr[j-h]=temp;
}
}
}
}
return arr;
}
时间复杂度:O(n^1.3);
空间复杂度:O(1);
稳定性:不稳定
5.快速排序
//快速排序
public static int[] QuickSort(int[] arr,int start,int end){
if(start<end){
int index=getIndex(arr,start,end);
QuickSort(arr,start,index-1);
QuickSort(arr,index+1,end);
}
return arr;
}
public static int getIndex(int[] arr,int start,int end){
int i=start;
int j=end;
int ret=arr[i];
while(i<j){
//从后往前,找一个比基准值小的数
while(i<j && arr[j]>ret){
j--;
}
//当走到这一步,如果i<j,就说明,从后往前遍历的过程中,已经找到了那个比 基准值小的值
if(i<j){
arr[i]=arr[j];
i++;
}
//现在从前往后遍历,找一个比基准值大的数
while(i<j && arr[i]<ret){
i++;
}
if(i<j){
arr[j]=arr[i];
j--;
}
}
//当出了这个循环,就说明i==j
arr[i]=ret;
return i;
}
时间复杂度:O(N*log2 N);
空间复杂度:O(log2 N);
稳定性:不稳定
6.归并排序
//归并排序:分而治之
public static void MergeSort(int[] arr){
//先拆分后归并
chaifen(arr,0,arr.length-1);
System.out.println(Arrays.toString(arr));
}
public static void chaifen(int[] arr,int start,int end){
//将数组进行拆分
int center=(start+end)/2;
if(start<end){
//拆分左边
chaifen(arr,start,center);
//拆分右边
chaifen(arr,center+1,end);
//当全部拆分完成之后,开始进行归并
guibing(arr,start,center,end);
}
}
public static void guibing(int[] arr,int start,int center,int end) {
int i = start;
int j = center + 1;
//定义新数组的下标
int index = 0;
//创建一个临时数组
int[] temp = new int[end - start + 1];
while (i <= center && j <= end) {
if (arr[i] <= arr[j]) {
temp[index] = arr[i];
i++;
} else {
temp[index] = arr[j];
j++;
}
index++;
}
//处理剩余元素
while (i <= center) {
temp[index] = arr[i];
i++;
index++;
}
while (j <= end) {
temp[index] = arr[j];
j++;
index++;
}
for(int m=0;m<temp.length;m++){
arr[m+start]=temp[m];
}
}
时间复杂度:O(N*log2 N);
空间复杂度:O(n);
稳定性:稳定
7.基数排序
public static void CardinalitySort(int [] arr){
//遍历数组,找到数组中的最大值
int max=getMax(arr);
//计算最大值有几位数 把int类型转化为String 类型,然后,计算其具体长度
int len=String.valueOf(max).length();
//定义一个二维数组,相当于10个桶
int[][] ret=new int[10][arr.length];
//定义一个统计数组
int[] counts=new int[10];
//进入循环
for(int i=0,n=1;i<len;i++,n*=10){
for(int j=0;j<arr.length;j++){
//取每一个元素,让这些元素入桶
int ys=arr[j]/n%10;
ret[ys][counts[ys]++]=arr[j];
}
//取出每一个元素
int index=0;
for(int k=0;k<counts.length;k++){
if(counts[k]!=0){
for(int m=0;m<counts[k];m++){
arr[index]=ret[k][m];
index++;
}
}
//清除上一次统计的个数
counts[k]=0;
}
}
System.out.println(Arrays.toString(arr));
}
public static int getMax(int[] arr){
int flag=arr[0];
for(int i=1;i<arr.length;i++){
if(arr[i]>flag){
flag=arr[i];
}
}
return flag;
}
时间复杂度:O(k*(m+n));
空间复杂度:O(m+n);
稳定性:稳定
8.堆排序
//堆排序
public static void HeapSort(int[] arr){
int startIndex=(arr.length-1)/2;
for(int i=startIndex;i>=0;i--){
HeapSort2(arr,arr.length,i);
}
System.out.println(Arrays.toString(arr));
//此刻,已经调整为了大顶堆;大顶堆的特性是:1.是一棵完全二叉树;2.它的所有父节点都大于它的子节点
//现在,需要将 堆顶元素和当前树的最后一个节点值进行交换
for(int i=arr.length-1;i>0;i--){
int t=arr[0];
arr[0]=arr[i];
arr[i]=t;
//此时,已经将最大元素放在了数组最后,以此类推,将每回的最大值都放在数组的后面,最后,数组就变成了一个升序的数组
//此时,需要继续调整剩下元素,让剩下的元素,继续呈 大顶堆的样子
HeapSort2(arr,i,0);
}
System.out.println(Arrays.toString(arr));
}
//这个方法的主要目的是:调整为大顶堆的格式
public static void HeapSort2(int[] arr,int size,int index){
int maxIndex=index;
int leftNode=index*2+1;
int rightNode=index*2+2;
if(leftNode<size && arr[leftNode]>arr[maxIndex]){
maxIndex=leftNode;
}
if(rightNode<size && arr[rightNode]>arr[maxIndex]){
maxIndex=rightNode;
}
if(index!=maxIndex){
//如果此时 最大值节点和传过来的节点不是同一个节点的话,需要交换两个节点的值
int t=arr[maxIndex];
arr[maxIndex]=arr[index];
arr[index]=t; //目的就是 让当前的节点的值最大(也就是说,当前节点的值比它的左右子节点的值都大)
//此时,虽然当前节点 以及它的左右子节点是 大顶堆的格式,但是,它的子节点以及子节点的子节点不一定是大顶堆了,此刻,需要继续调整
HeapSort2(arr,size,maxIndex);
}
}
时间复杂度:O(n*log2 N);
空间复杂度:O(1);
稳定性:不稳定