排序算法汇总

十大经典排序算法详细总结(含JAVA代码实现)_Java学习之道-CSDN博客

​​​​​​算法的时间与空间复杂度(一看就懂)_不止思考-CSDN博客_空间复杂度

冒泡排序

直接交换

代码

int[] arr={23,12,14,34,1,0,34};
        for(int i=0;i<arr.length;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;
                    }
                }  
            }
        for(int i=0;i<arr.length;i++){
            System.out.println(arr[i]);
        }}

选择排序

先记录再交换

代码

     //选择排序
        int[] arr = {23, 12, 14, 34, 1, 0, 34};
        int min=arr[0];
        for(int i=0;i<arr.length;i++) {
            int index=i;
            for (int j = i + 1; j < arr.length; j++) {
                if (arr[j]<arr[index] ) index=j;
            }
            int temp=arr[i];
            arr[i]=arr[index];
            arr[index]=temp;
        }
        for(int i:arr) System.out.println(i);

简单快速排序

对冒泡的一种改进,二分思想

快速排序(java实现)_王玉Student的博客-CSDN博客_java快速排序

ublic static void main(String[] args) {
    //快速排序(二分思想)
        int[]arr={12,2,34,45,21,3};
     quicksort(arr,0,arr.length-1);
       for(int i:arr) System.out.println(i);
    }
     private static void quicksort(int[]arr,int start,int end){
        //递归出口否则会栈溢出
        if(start>end) return;
        //因为start和end不能变  所以用一个变量来存储
        int l=start,r=end;
        int priov=arr[l];
        while(l<r){
           /* 假如最好的情况是一个有序序列 1 3 5 7 9,如果先从左边开始寻找的话,一直往右寻找大于1的数,直到i变成4还没有找到就停止了;但是下面的语句就会把9赋值在1上了。
如果先从右边开始寻找的话,一直往左寻找小于1的数,直到j变成0还没有找到然后停止,此时i和j都是0,所以就是把自身交换一下并不影响顺序。
         * 这也是为什么强调如果选择数组左边第一个数作为基准值的时候,得先从右边开始查找数。*/
            while(arr[r]>=priov && l<r) r--;
            while (arr[l]<=priov && l<r) l++;
            int temp=arr[l];
            arr[l]=arr[r];
            arr[r]=temp;
        }
        //后将基准位与i和j相等位置的数字交换
         //下面的i和j其实相等的,所以用哪一个都一样
        arr[start]=arr[l];
        arr[l]=priov;
        quicksort(arr,start,r-1);
        quicksort(arr,r+1,end);
     }

堆排序

堆排序详解 - 前程明亮 - 博客园

堆排序_guanlovean-CSDN博客_堆排序

白话讲排序系列(六) 堆排序(绝对让你明白堆排序!)_夜阑听风-CSDN博客_堆排序

【堆本质:1.完全二叉树+2.所有父节点的值都大于(小于)子节点的值】

大顶堆{降序}、小顶堆{升序}

概念:若在输出堆顶的最小值(最大值)后,使得剩余n-1个元素的序列重又建成一个堆,则得到n个元素的次小值((次大值)..…如此反复,便能得到一个有序序列,这个过程称之为堆排序。

在完全二叉树中所有以叶子结点(序号i > n/2)为根的子树是堆。

从最后一个非叶子节点(n/2),依次进行调整(n/2-1、n/2-2...1).

1.父结点索引:(i-1)/2(这里计算机中的除以2,省略掉小数)

2.左孩子索引:2*i+1

3.右孩子索引:2*i+2

对于大顶堆:arr[i] >= arr[2i + 1] && arr[i] >= arr[2i + 2]

对于小顶堆:arr[i] <= arr[2i + 1] && arr[i] <= arr[2i + 2]

堆结构在逻辑上是完全二叉树,物理存储上是数组

public class paixu {
    //堆排序
    public static void main(String[] args) {
        int[] arr=new int[]{2,1,4,3,6,5,8,7};
        System.out.println("排序前"+Arrays.toString(arr));
            heapsort(arr);
        System.out.println("排序前"+Arrays.toString(arr));

    }
    public static void heapsort(int[] arr){
        int len=arr.length;
        //构建大顶堆,就是把待排序序列,变成一个大顶堆结构的数组
        //从最后一个叶子节点开始从下至上,从右至左,向前遍历,调整节点性质,使之成为大顶堆。
        for(int i=len/2-1;i>=0;i--){
            //初始化时 从最后一个有子节点往上调整最大堆。
            heapify(arr,i,len);
        }
        //交换栈顶和当前得末尾的节点,重置大顶堆
        for(int i=len-1;i>0;i--){
            // 元素交换
            // 说是交换,其实质就是把大顶堆的根元素,放到数组的最后;换句话说,就是每一次的堆调整之后,都会有一个元素到达自己的最终位置
            swap(arr,0,i);
            //元素交换之后,毫无疑问,最后一个元素无需再考虑排序问题了。
            // 接下来我们需要排序的,就是已经去掉了部分元素的堆了,这也是为什么此方法放在循环里的原因
            // 而这里,实质上是自上而下,自左向右进行调整的
            //当有一个元素弹出到末尾时,下一次的调整从开头开始【即0】。从顶点开始往下调整,自上而下,自左到右  
            // 无需考虑最后一个元素 所以放到循环里
            heapify(arr,0,i);
        }
    }
    //自上到下,自左到右的一点点调整整棵树,
    public static void heapify(int[] arr,int i,int len){
        //先根据堆的性质,找出他的左右节点的索引
        int left=2*i+1;
        int right=2*i+2;
        //默认当前节点(父节点)是最大值
        int largestIndex=i;
        //如果有左节点,并且左节点的值更大,更新最大值的索引
        if(left<len && arr[left]>arr[largestIndex]){
            largestIndex=left;
        }
        //如果有右节点,并且右节点的值更大,更新最大值的索引
        if(right<len && arr[right]>arr[largestIndex]){
            largestIndex=right;
        }

        if(largestIndex!=i){
            //如果最大值不是当前非叶子节点的值,那么就把当前节点和最大值的子节点互换。
            swap(arr,largestIndex,i);
            //因为互换以后,子节点的值遍历,如果该节点也有自己的子节点,仍需再次调整。
            heapify(arr,largestIndex,len);
        }
    }
    public static  void  swap(int[] arr,int a,int b){
        int temp=arr[a];
        arr[a]=arr[b];
        arr[b]=temp;
    }

插入排序

直接插入排序【顺序法定位插入排序】

二分插入排序【二分法定位插入排序】

希尔排序【缩小增量】

public static void main(String[] args) {
        int[] arr=new int[]{4,1,34,12,25,8};
        insort(arr);
        for(int a:arr){
            System.out.println(a);
        }
    }
    public static int[] insort(int[]arr){
        if(arr.length==0) return arr;
        int current,j;
        //i表示无序的第一个元素 即要插入的元素 j表示寻找插入位置时的下标
        for(int i=1;i<arr.length;i++){
            if(arr[i]>arr[i-1]) continue;
            //一次查找
            //复制插入元素
            current=arr[i];
            //记录后移,查找插入位置
            for(j=i-1;j>=0&&current<arr[j];j--){
                arr[j+1]=arr[j];
            }
            //将插入元素插入到正确位置
            arr[j+1]=current;
        }
        return arr;
    }

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值