几种常见的排序

1.冒泡排序

    public static int[] Bubble(int[] arr){
        for(int i=0;i<arr.length-1;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;
                }
            }
        }
        return arr;
    }

时间复杂度:O(n^2);
空间复杂度:O(1);
稳定性:稳定

2.直接插入排序

  //直接插入排序
    public static int[] Selection(int[] arr){
        for(int i=1;i<arr.length;i++){
            for(int j=i;j>0;j--){
                if(arr[j]<arr[j-1]){
                    int temp=arr[j];
                    arr[j]=arr[j-1];
                    arr[j-1]=temp;
                }
            }
        }
        return arr;
    }

时间复杂度:O(n^2);
空间复杂度:O(1);
稳定性:稳定

3.选择排序

public static int[] SelectionSort(int[] arr){
        for(int i=0;i<arr.length;i++){
            for(int j=i+1;j<arr.length;j++){
                if(arr[i]>arr[j]){
                    int temp=arr[i];
                    arr[i]=arr[j];
                    arr[j]=temp;
                }
            }
        }
        return arr;
    }

时间复杂度:O(n^2);
空间复杂度:O(1);
稳定性:不稳定

4.希尔排序

 //希尔排序
    public static int[] ShellSort(int[] arr){
      int gap=1;
      while(gap<arr.length/3){
          gap=gap*3+1;
      }
      for(int h=gap;h>0;h=(h-1)/3){
          for(int i=h;i<arr.length;i++){
              for(int j=i;j>h-1;j=j-h){
                  if(arr[j]<arr[j-h]){
                      int temp=arr[j];
                      arr[j]=arr[j-h];
                      arr[j-h]=temp;
                  }
              }
          }
      }
        return arr;
    }

时间复杂度:O(n^1.3);
空间复杂度:O(1);
稳定性:不稳定

5.快速排序

 //快速排序
    public static int[] QuickSort(int[] arr,int start,int end){
        if(start<end){
            int index=getIndex(arr,start,end);
            QuickSort(arr,start,index-1);
            QuickSort(arr,index+1,end);
        }
      return arr;
    }
    public static int getIndex(int[] arr,int start,int end){
        int i=start;
        int j=end;
        int ret=arr[i];
        while(i<j){
            //从后往前,找一个比基准值小的数
            while(i<j && arr[j]>ret){
                j--;
            }
            //当走到这一步,如果i<j,就说明,从后往前遍历的过程中,已经找到了那个比 基准值小的值
            if(i<j){
                arr[i]=arr[j];
                i++;
            }
            //现在从前往后遍历,找一个比基准值大的数
            while(i<j && arr[i]<ret){
                i++;
            }
            if(i<j){
                arr[j]=arr[i];
                j--;
            }
        }
        //当出了这个循环,就说明i==j
        arr[i]=ret;
        return  i;
    }

时间复杂度:O(N*log2 N);
空间复杂度:O(log2 N);
稳定性:不稳定

6.归并排序

    //归并排序:分而治之
    public static void MergeSort(int[] arr){
        //先拆分后归并
       chaifen(arr,0,arr.length-1);
        System.out.println(Arrays.toString(arr));
    }
    public static void chaifen(int[] arr,int start,int end){
        //将数组进行拆分
        int center=(start+end)/2;
        if(start<end){
          //拆分左边
            chaifen(arr,start,center);
            //拆分右边
            chaifen(arr,center+1,end);
            //当全部拆分完成之后,开始进行归并
            guibing(arr,start,center,end);
        }
    }
    public static void guibing(int[] arr,int start,int center,int end) {
        int i = start;
        int j = center + 1;
        //定义新数组的下标
        int index = 0;
        //创建一个临时数组
        int[] temp = new int[end - start + 1];
        while (i <= center && j <= end) {
            if (arr[i] <= arr[j]) {
                temp[index] = arr[i];
                i++;
            } else {
                temp[index] = arr[j];
                j++;
            }
            index++;
        }
        //处理剩余元素
        while (i <= center) {
            temp[index] = arr[i];
            i++;
            index++;
        }
        while (j <= end) {
            temp[index] = arr[j];
            j++;
            index++;
        }
        for(int m=0;m<temp.length;m++){
            arr[m+start]=temp[m];
        }
    }

时间复杂度:O(N*log2 N);
空间复杂度:O(n);
稳定性:稳定

7.基数排序

public static void CardinalitySort(int [] arr){
        //遍历数组,找到数组中的最大值
        int max=getMax(arr);
        //计算最大值有几位数     把int类型转化为String 类型,然后,计算其具体长度
        int len=String.valueOf(max).length();
        //定义一个二维数组,相当于10个桶
        int[][] ret=new int[10][arr.length];
        //定义一个统计数组
        int[] counts=new int[10];
        //进入循环
        for(int i=0,n=1;i<len;i++,n*=10){
            for(int j=0;j<arr.length;j++){
                //取每一个元素,让这些元素入桶
                int ys=arr[j]/n%10;
                ret[ys][counts[ys]++]=arr[j];
            }
            //取出每一个元素
            int index=0;
            for(int k=0;k<counts.length;k++){
                if(counts[k]!=0){
                    for(int m=0;m<counts[k];m++){
                        arr[index]=ret[k][m];
                        index++;
                    }
                }
                //清除上一次统计的个数
                counts[k]=0;
            }
        }
        System.out.println(Arrays.toString(arr));
    }
    public static int getMax(int[] arr){
        int flag=arr[0];
        for(int i=1;i<arr.length;i++){
            if(arr[i]>flag){
                flag=arr[i];
            }
        }
        return flag;
    }

时间复杂度:O(k*(m+n));
空间复杂度:O(m+n);
稳定性:稳定

8.堆排序

//堆排序
    public static void HeapSort(int[] arr){
        int startIndex=(arr.length-1)/2;
        for(int i=startIndex;i>=0;i--){
            HeapSort2(arr,arr.length,i);
        }
        System.out.println(Arrays.toString(arr));
        //此刻,已经调整为了大顶堆;大顶堆的特性是:1.是一棵完全二叉树;2.它的所有父节点都大于它的子节点
        //现在,需要将 堆顶元素和当前树的最后一个节点值进行交换
        for(int i=arr.length-1;i>0;i--){
            int t=arr[0];
            arr[0]=arr[i];
            arr[i]=t;
            //此时,已经将最大元素放在了数组最后,以此类推,将每回的最大值都放在数组的后面,最后,数组就变成了一个升序的数组
            //此时,需要继续调整剩下元素,让剩下的元素,继续呈 大顶堆的样子
            HeapSort2(arr,i,0);
        }
        System.out.println(Arrays.toString(arr));
    }
    //这个方法的主要目的是:调整为大顶堆的格式
    public static void HeapSort2(int[] arr,int size,int index){
        int maxIndex=index;
        int leftNode=index*2+1;
        int rightNode=index*2+2;
        if(leftNode<size && arr[leftNode]>arr[maxIndex]){
            maxIndex=leftNode;
        }
        if(rightNode<size && arr[rightNode]>arr[maxIndex]){
            maxIndex=rightNode;
        }
        if(index!=maxIndex){
            //如果此时 最大值节点和传过来的节点不是同一个节点的话,需要交换两个节点的值
            int t=arr[maxIndex];
            arr[maxIndex]=arr[index];
            arr[index]=t;           //目的就是 让当前的节点的值最大(也就是说,当前节点的值比它的左右子节点的值都大)
            //此时,虽然当前节点 以及它的左右子节点是 大顶堆的格式,但是,它的子节点以及子节点的子节点不一定是大顶堆了,此刻,需要继续调整
            HeapSort2(arr,size,maxIndex);
        }
    }

时间复杂度:O(n*log2 N);
空间复杂度:O(1);
稳定性:不稳定

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值