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]--;
            }
        }
    }
相关推荐
2301_7657031413 小时前
C++中的职责链模式实战
开发语言·c++·算法
好好研究13 小时前
Spring Boot - Thymeleaf模板引擎
java·spring boot·后端·thymeleaf
爬山算法13 小时前
Hibernate(76)如何在混合持久化环境中使用Hibernate?
java·后端·hibernate
编程彩机13 小时前
互联网大厂Java面试:从分布式缓存到消息队列的技术场景解析
java·redis·面试·kafka·消息队列·微服务架构·分布式缓存
StandbyTime13 小时前
《算法笔记》学习记录-第一章
c++·算法·算法笔记
她说..13 小时前
策略模式+工厂模式实现单接口适配多审核节点
java·spring boot·后端·spring·简单工厂模式·策略模式
近津薪荼14 小时前
优选算法——双指针8(单调性)
数据结构·c++·学习·算法
松☆14 小时前
Dart 中的常用数据类型详解(含 String、数字类型、List、Map 与 dynamic) ------(2)
数据结构·list
格林威14 小时前
Baumer相机铆钉安装状态检测:判断铆接是否到位的 5 个核心算法,附 OpenCV+Halcon 的实战代码!
人工智能·opencv·算法·计算机视觉·视觉检测·工业相机·堡盟相机
坚持就完事了14 小时前
Java的OOP
java·开发语言