java实现排序

冒泡排序

每次排序都会把最大的元素放到最后一个位置,排序的时候和冒泡很像,一个一个的冒泡。

java 复制代码
//冒泡排序,每次把一个排好的数字放在最后的位置
    public static void bubbleSort(int []nums){
        int n= nums.length;
        int end=n-1;
        while(true){
            int exchange=0;//记录每层循环中数据交换的次数
            for(int i=0;i<end;i++){
                if(nums[i]>nums[i+1]){
                    swap(nums,i,i+1);
                    exchange++;
                }
            }
            if(exchange==0)break;//交换次数为零说明交换完毕
        }

    }

快速排序,使用的是分段排序的方法,每次以第一个元素作为标准值,然后从后往前遍历,找到第一个比标准值小的元素,和low位置交换。接着就从前往后遍历,找到第一个比标准值大的元素,交换位置。

java 复制代码
 //快速排序
    public static void quickSort(int[]nums,int i,int j){
        if(i<j){
            int part=partition(nums,i,j);
            quickSort(nums,i,part-1);
            quickSort(nums,part+1,j);
        }
    }
    public static int partition(int[]nums,int low,int high){
        int tmp=nums[low];//第一个元素作为标准
        while(low<high){
            //从后往前找到第一个小于tmp的元素
            while(low<high&&nums[high]>=tmp){
                high--;
            }
            if(low<high){
                nums[low]=nums[high];
            }
            //从前往后找到第一个大于tmp的元素
            while(low<high&&nums[low]<=tmp){
                low++;
            }
            if(low<high){
                nums[high]=nums[low];
            }
        }
        nums[low]=tmp;
        return low;
    }

插入排序,从第二个元素开始,然后往前遍历,如果这个元素比当前索引位置的元素大,这个元素就需要后移动。

java 复制代码
//插入排序,每次枚举当前位置的元素,然后往前遍历,比自己大的元素往后移动
    public static void insertSort(int []nums){
        int n=nums.length;
        for(int i=1;i<n;i++){
            int tmp=nums[i];
            int j=i-1;
            //往前搜索,遇到比当前元素大的往后移动
            while(j>=0&&nums[j]>=tmp){
                nums[j+1]=nums[j--];
            }
            nums[j+1]=tmp;
        }
    }

希尔排序,步长不是1,而是d。

java 复制代码
//希尔排序
    public static void shellSort(int[]nums){
        int len=nums.length;
        for(int d=len/2;d>0;d/=2){
            for(int i=d;i<len;i++){
                int tmp=nums[i];
                int j;
                for(j=i-d;j>=0;j-=d){
                    if(nums[j]>=tmp){
                        nums[j+d]=nums[j];
                    }else{
                        break;//退出循环
                    }
                }
                nums[j+d]=tmp;
            }
        }
    }

选择排序,每次选择最小的元素,进行交换位置

java 复制代码
 //选择排序,每次找到最小的元素,与当前位置直接交换
    public static void selectSort(int[]nums){
        int n=nums.length;
        for(int i=0;i<n-1;i++){
            int k=i;//记录当前的位置
            for(int j=i+1;j<n;j++){
                //循环找到一个最小的
                if(nums[j]<=nums[k])k=j;
            }
            if(k!=i){
                swap(nums,i,k);
            }
        }
    }

堆排序

java 复制代码
public static void heapSort(int[]nums){
        int n=nums.length-1;
        //进行筛选,n/2是第一个非叶子节点
        for(int i=n/2;i>=0;i--){
            heapShift(nums,i,n);
        }
        //大根堆构建完毕,开始排序,每次从堆顶获取最大的元素放在数组的最后一个位置
        for(int i=n;i>0;i--){
            int tmp=nums[0];
            nums[0]=nums[i];
            nums[i]=tmp;
            heapShift(nums,0,i-1);
        }

    }
    public static void heapShift(int []nums,int i,int n){
        //从i到n是满足大根堆的
        int tmp=nums[i];
        int j=i*2+1;//左子树节点,完全二叉树
        while(j<=n){
            if(j<n&&nums[j]<nums[j+1]){
                j++;//变成右子树
            }
            if(tmp>nums[j])break;//筛选结束
            nums[i]=nums[j];//大的元素往上移动
            i=j;
            j=2*j;
        }
        nums[i]=tmp;
    }

归并排序,先分治到数组的个数只有一个的时候,再使用两个数组进行合并

java 复制代码
public static int[] mergeSort(int[]nums){
        return divide(nums,0,nums.length);
    }
    public static int[]divide(int[]nums,int i,int j){
        int m=j-i;
        if(j-i==0){
            return new int[]{};
        }
        if(j-i==1){
            return new int[]{nums[i]};
        }
        int[]left=divide(nums,i,i+m/2);
        int[]right=divide(nums,i+m/2,j);
        return merge(left,right);
    }
    public static int[]merge(int[]left,int[]right){
        int[]p=new int[left.length+right.length];
        int k=0;
        int i=0;
        int j=0;
        while(i<=left.length-1&&j<=right.length-1){
            if(left[i]<right[j]){
                p[k++]=left[i++];
            }else{
                p[k++]=right[j++];
            }
        }
        while(i<=left.length-1){
            p[k++]=left[i++];
        }
        while(j<=right.length-1){
            p[k++]=right[j++];
        }
        return p;
    }

桶排序(计数排序),使用一个数组记录每个元素出现的次数。

maxLength>Math.max(nums)

java 复制代码
//桶排序,就是使用一个数组,下标的位置就是某个元素
    public static void bulkSort(int[]nums,int maxLength){
        int[]max=new int[maxLength];
        for(int num:nums){
            max[num]++;
        }
        for(int i=0,j=0;i<maxLength;i++){
            while(max[i]!=0){
                nums[j++]=i;
                max[i]--;
            }
        }
    }
相关推荐
考虑考虑8 小时前
JDK26中的Map.ofLazy
java·后端·java ee
鶴哥只手遮天12 小时前
Spring AI 2.0.1 深度解析-第 14 章 MCP 服务端(上):注解式实现与工具来源
java·人工智能·开源
鶴哥只手遮天12 小时前
Spring AI 2.0.1 深度解析-第 15 章 MCP 服务端(下):三种协议形态、Streamable 传输与状态管理
java·人工智能·开源
鶴哥只手遮天12 小时前
Spring AI 2.0.1 深度解析-第 16 章 向量存储(上):`VectorStore` 接口体系、`BatchingStrategy`
java·人工智能·开源
鶴哥只手遮天12 小时前
Spring AI 2.0.1 深度解析-第 12 章 工具循环的流式形态、Usage 累加与扩展体系
java·人工智能·开源
鶴哥只手遮天12 小时前
Spring AI 2.0.1 深度解析-第 23 章 模型供应商实现:从 `OpenAiSetup` 到 Bedrock
java·人工智能·开源
鶴哥只手遮天12 小时前
Spring AI 2.0.1 深度解析-第 06 章 内置 Advisor 全景:13 个实现逐个剖到源码级
java·人工智能·开源
鶴哥只手遮天12 小时前
Spring AI 2.0.1 深度解析-第 03 章 消息体系与 Prompt:不可变模型、`ChatOptions` 与模板渲染
java·人工智能·开源
鶴哥只手遮天12 小时前
Spring AI 2.0.1 深度解析-第 24 章 生产实践与 2.x 迁移:陷阱清单、AOT 与调优
java·人工智能·开源
鶴哥只手遮天12 小时前
Spring AI 2.0.1 深度解析-第 10 章 工具调用(中):执行链路、结果转换与工具限制
java·人工智能·开源