import java.util.*;
public class Solution {
/**
* 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
* 将给定数组排序
* @param arr int整型一维数组 待排序的数组
* @return int整型一维数组
*/
public int[] MySort(int[] arr) {
// 选择排序
// return selectSort(arr);
// 冒泡排序
// return bubbleSort(arr);
// 插入排序
// return insertSort(arr);
// 希尔排序
// return shellSort(arr);
// 归并排序
// return mergeSort(arr,0,arr.length-1);
// 快速排序
// quickSort(arr,0,arr.length-1);
// return arr;
// 计数排序
// return countSort(arr);
// 基数排序
// return radixSort(arr);
// 桶排序
return bucketSort(arr);
}
// 选择排序---选择最小的数与当前数交换
public int[] selectSort(int[] arr){
if(arr.length<2)return arr;
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);
}
return arr;
}
// 冒泡排序---两两比较交换
public int[] bubbleSort(int[] arr){
if(arr.length<2) return arr;
for(int i = 0;i<arr.length;i++){
for(int j = i+1;j<arr.length;j++){
if(arr[i]>arr[j])swap(arr,i,j);
}
}
return arr;
}
// 插入排序---与当前位置之前的所有元素比
public int[] insertSort(int[] arr){
if(arr.length<2)return arr;
for(int i=1;i<arr.length;i++){
for(int j=i;j>0;j--){
if(arr[j]<arr[j-1])swap(arr,j,j-1);
}
}
return arr;
}
// 希尔排序---以间隔分组分别排序,间隔缩短再排序,直至缩短成间隔为1,升级版插入排序
public int[] shellSort(int[] arr){
// gap的设定,根据Knuth序列定义,左程云视频
int h = 1;
while(h <= arr.length / 3){
h = h*3 + 1;
}
for(int gap =h;gap>0;gap=(gap-1)/3){
for(int i=gap;i<arr.length;i++){
for(int j=i;j-gap>=0;j=j-gap){
if(arr[j]<arr[j-gap])swap(arr,j,j-gap);
}
}
}
return arr;
}
// 归并排序---找个中间轴,左边排序好,右边排序好,然后左边右边合并起来,其中每一边排序时再划中间轴,直到相隔两个数进行排序
public int[] mergeSort(int[] arr,int left,int right){
if(left==right)return arr;
int mid = left + (right - left)/2;
// 左边排序
mergeSort(arr,left,mid);
// 右边排序
mergeSort(arr,mid+1,right);
// 合并
merge(arr,left,mid+1,right);
return arr;
}
// 两个排好序的数组合并,start 左数组起点,end 右数组起点,right 右数组终点
public void merge(int[] arr,int start,int end,int right){
// mid为两个有序数组的分界点
int i = start,j=end,k=0,mid=end-1;
int[] temp = new int[right-start+1];
while(i<=mid && j<=right){
if(arr[i]<=arr[j]){
temp[k] = arr[i];
k++;i++;
}else{
temp[k] = arr[j];
k++;j++;
}
}
// 剩余数组直接接龙
while(i<=mid)temp[k++]=arr[i++];
while(j<=right)temp[k++]=arr[j++];
// 赋值原数组
for(int m=0;m<k;m++){
arr[start+m] = temp[m];
}
}
// 快速排序---选择中轴数,左边向右,右边向左,分别与中轴数比较,大小交换,中轴数与左指针交换,左边递归,右边递归
public void quickSort(int[] arr,int left,int right){
if(left >= right) return ;
int pivot = arr[left];
int i = left,j = right;
while(i < j){
while(arr[j] >= pivot && j>i){
j--;
}
while(arr[i] <= pivot && i<j){
i++;
}
if(i < j){
swap(arr,i,j);
}
}
swap(arr,left,i);
//左子数组
quickSort(arr,left,j-1);
//右子数组
quickSort(arr,j+1,right);
}
// 计数排序---不适合,数据量比数据范围小
public int[] countSort(int[] arr){
int[] newArr = new int[arr.length];
int[] countArr = new int[6];
for(int i=0;i<arr.length;i++){
countArr[arr[i]]++;
}
for(int i=1,j=0;i<countArr.length;i++,j++){
while(countArr[i]--!=0){
newArr[j++]=i;
}
}
return newArr;
}
// 基数排序---二维数组,10*数组长度,从个位数一直到最大位数,分别排序重组
public int[] radixSort(int[] arr){
// 找到最大位数
int max = 1;
for(int i=0;i<arr.length;i++){
int count = 1;
int temp = arr[i];
while(temp/10>0){count++;temp = temp/10;}
if(count>max)max = count;
}
for(int m=0;m<max;m++){
int[][] countArr = new int[10][arr.length];
for(int i=0;i<arr.length;i++){
int n = m;
int temp = arr[i];
while(n-->0){temp=temp/10;}
int result = temp%10;
for(int k=0;k<countArr[result].length;k++){
if(countArr[result][k]==0){
countArr[result][k]=arr[i];
break;
}
}
}
// 重组数组
arr = reGroup(countArr,arr.length);
}
return arr;
}
// 重组数组
public int[] reGroup(int[][] countArr,int length){
int[] arr = new int[length];
int k=0;
for(int i=0;i<countArr.length;i++){
for(int j=0;j<countArr[i].length;j++){
if(countArr[i][j]>0){
arr[k++] = countArr[i][j];
}
}
}
return arr;
}
// 桶排序---给定n个桶,找到最大数与最小数,计算出每个桶能装的数的范围,将数分别放入符合条件的桶中,对每个桶进行快速排序,最后合并
public int[] bucketSort(int[] arr){
// 设置桶的个数
int bucket = 4;
// 找到数组中的最大最小值
int min = arr[0],max=arr[0];
for(int i=0;i<arr.length;i++){
if(arr[i]>max)max=arr[i];
if(arr[i]<min)min=arr[i];
}
// 每个桶盛数的范围
int range = (max-min)/bucket;
int[][] newArr = new int[bucket][arr.length];
for(int i =0;i<arr.length;i++){
int temp = arr[i];
if(temp >= min && temp < min+range){
for(int k =0;k<newArr[0].length;k++){
if(newArr[0][k]==0){
newArr[0][k] = arr[i];
break;
}
}
}
if(temp >= min+range && temp < min+2*range){
for(int k =0;k<newArr[0].length;k++){
if(newArr[1][k]==0){
newArr[1][k] = arr[i];
break;
}
}
}
if(temp >= min+2*range && temp < max - range){
for(int k =0;k<newArr[0].length;k++){
if(newArr[2][k]==0){
newArr[2][k] = arr[i];
break;
}
}
}
if(temp >= max - range && temp <= max){
for(int k =0;k<newArr[0].length;k++){
if(newArr[3][k]==0){
newArr[3][k] = arr[i];
break;
}
}
}
}
// 对每个桶进行排序
for(int i=0;i<newArr.length;i++){
quickSort(newArr[i],0,newArr[i].length-1);
}
// 重组数组
return reGroup(newArr,arr.length);
}
// 交换位置
public void swap(int[] arr,int i,int j){
int temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
}