import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
public class 十大排序 {
//冒泡排序-冒泡至最后
public static void test1(int[] nums){
for (int i=0;i<nums.length-1;i++){
for (int j=0;j<nums.length-i-1;j++){
if (nums[j+1]<nums[j]){
int temp = nums[j+1];
nums[j+1]=nums[j];
nums[j]=temp;
}
}
}
}
//选择排序-选择最小的放入第一个
public static void test2(int[] nums){
for (int i=0;i<nums.length;i++){
int minIndex = i;
for (int j=i;j<nums.length;j++){
if (nums[j]<nums[minIndex]){
minIndex=j;
}
}
//进行交换
int temp = nums[minIndex];
nums[minIndex]=nums[i];
nums[i]=temp;
}
}
//直接插入排序-前面是已排序好的
public static void test3(int[] nums){
for (int i=1;i<nums.length;i++){
//找出要插入的位置
int insertValue = nums[i];
int j=i-1;
//将具体的数插入进去
for (;j>=0;j--){
if (insertValue<nums[j]){
nums[j+1]=nums[j];
}else{
break;
}
}
nums[j+1]=insertValue;
}
}
//希尔排序-以k为节点进行数据插入
public static void test4(int[] nums){
int n=nums.length;
//插入的步数
for (int step=n/2;step>=1;step=step/2){
//进行插入数据
for (int i=step;i<n;i++){
int insertValue = nums[i];
int j=i-step;
for (;j>=0;j-=step){
if (nums[j]>insertValue){
nums[j+step]=nums[j];
}else{
break;
}
}
//进行插入
nums[j+step]=insertValue;
}
}
}
//快速排序-找出中间点
public static void test5(int[] nums){
quickSort(nums,0,nums.length-1);
}
public static void quickSort(int[] nums, int left, int right){
if (left>=right){
return;
}
int target = nums[left];
int i=left;
int j=right;
while (i<=j){
if (nums[i]<=target){
i++;
}else if (nums[j]>=target){
j--;
}else{
//进行交换
int temp=nums[i];
nums[i]=nums[j];
nums[j]=temp;
}
}
//进行交换
nums[left]=nums[j];
nums[j]=target;
quickSort(nums,left,j-1);
quickSort(nums,j+1,right);
}
//归并排序-将待排序分为两个部分
public static int[] test6(int[] nums){
return mergeSort(nums, 0, nums.length - 1);
}
public static int[] mergeSort(int[] nums, int left, int right){
if (left>=right){
return new int[]{nums[left]};
}
int mid = (left+right)/2;
int[] leftNums = mergeSort(nums, left, mid);
int[] rightNums = mergeSort(nums, mid + 1, right);
System.out.println(Arrays.toString(leftNums));
System.out.println(Arrays.toString(rightNums));
return merge(leftNums,rightNums);
}
//开始进行合并
public static int[] merge(int[] leftNums, int[] rightNums){
int[] resNums = new int[leftNums.length+rightNums.length];
int i=0;
int j=0;
int k=0;
while (i<leftNums.length&&j<rightNums.length){
if (leftNums[i]<rightNums[j]){
resNums[k++]=leftNums[i++];
}else{
resNums[k++]=rightNums[j++];
}
}
while (i<leftNums.length){
resNums[k++]=leftNums[i++];
}
while (j<rightNums.length){
resNums[k++]=rightNums[j++];
}
return resNums;
}
// 7
//4 8
//堆排序
public static void test7(int[] nums){
int n = nums.length;
//建立堆
for (int i=n/2-1;i>=0;i--){
createTree(nums,i,n);
}
//将堆头进行交换
for (int i=0;i<n;i++){
//进行交换
int temp=nums[0];
nums[0]=nums[n-i-1];
nums[n-i-1]=temp;
//再进行建树
createTree(nums,0,n-i-1);
}
}
//将节点k进行下沉
public static void createTree(int[] nums, int k, int n){
//将k往下移动
while (k<n/2){
//假设坐标是最大的
int largeIndex = k*2+1;
int rightIndex = k*2+2;
if (rightIndex<n&&nums[largeIndex]<nums[rightIndex]){
largeIndex=rightIndex;
}
if (nums[k]<nums[largeIndex]){
int temp=nums[k];
nums[k]=nums[largeIndex];
nums[largeIndex]=temp;
//向下移动
k=largeIndex;
}else{
break;
}
}
}
//计数排序
public static int[] test8(int[] nums){
int maxValue = nums[0];
int minValue = nums[0];
//找出最大值和最小值
for (int num : nums) {
if (num > maxValue) {
maxValue = num;
}
if (num < minValue) {
minValue = num;
}
}
int temp=0;
if (minValue<0){
temp=-minValue;
}
//建立一个新的数组
int[] newNums = new int[maxValue+temp+1];
System.out.println(Arrays.toString(newNums));
//进行计数
for (int num : nums) {
newNums[num+temp]=newNums[num+temp]+1;
}
//存储结果
int[] newResNums=new int[nums.length];
int k=0;
for (int i=0;i<newNums.length;i++){
for (int j=0;j<newNums[i];j++){
newResNums[k++]=i-temp;
}
}
return newResNums;
}
//桶排序 7 4 8 9 3
public static int[] test9(int[] nums) {
if (nums == null || nums.length == 0) {
return nums;
}
int maxValue = nums[0];
int minValue = nums[0];
int n = nums.length;
// 1. 查找最大值和最小值
for (int num : nums) {
if (num > maxValue) {
maxValue = num;
}
if (num < minValue) {
minValue = num;
}
}
//1 3 5 7
// 2. 确定桶的数量,这里选择 k = sqrt(n)
int bucketCount = (int) Math.sqrt(n);
if (bucketCount == 0) {
bucketCount = 1; // 至少一个桶
}
// 3. 计算每个桶的范围
double range = (double) (maxValue - minValue) / bucketCount;
// 4. 初始化桶
List<List<Integer>> buckets = new ArrayList<>(bucketCount);
for (int i = 0; i < bucketCount; i++) {
buckets.add(new ArrayList<>());
}
// 5. 分配元素到桶中
for (int num : nums) {
// 计算桶索引,避免浮点数运算带来的精度问题
int bucketIndex = (int) ((num - minValue) / range);
// 处理最大值的情况,确保它被分配到最后一个桶
if (bucketIndex >= bucketCount) {
bucketIndex = bucketCount - 1;
}
buckets.get(bucketIndex).add(num);
}
// 6. 对每个桶进行排序
for (List<Integer> bucket : buckets) {
Collections.sort(bucket);
}
// 7. 合并所有桶中的元素回原数组
int index = 0;
for (List<Integer> bucket : buckets) {
for (int num : bucket) {
nums[index++] = num;
}
}
return nums;
}
public static void test10(int[] nums) {
int maxValue = nums[0];
for (int i=0;i<nums.length;i++){
if (nums[i]>maxValue){
maxValue=nums[i];
}
}
int maxLength = (maxValue+"").length();
//桶
int[][] arr = new int[10][nums.length];
int[] arrCount = new int[10];
//总共要三次循环
for (int i=0;i<maxLength;i++){
//将数据放入桶中
for (int j=0;j<nums.length;j++){
int i1 = nums[j] / (int) (Math.pow(10, i)) % 10;
arr[i1][arrCount[i1]]=nums[j];
arrCount[i1]++;
}
//从桶中取出来放回去
int index=0;
for (int m=0;m<arr.length;m++){
for (int j=0;j<arrCount[m];j++){
nums[index++]=arr[m][j];
}
arrCount[m]=0;
}
}
}
public static void main(String[] args) {
int[] nums = new int[]{7,4,8,9,3,2,4,4,2};
test10(nums);
System.out.println(Arrays.toString(nums));
}
}