java 排序算法

排序算法

忽然感觉对一些基本的算法都有些陌生了,自己写一遍熟悉一下
在这里插入图片描述

内部排序

交换排序

快速排序
  1. 以首部为基准开始进行分割扫描,分为两部分(小的在前大的在后)
  2. 循环调整位置。
  3. 分别对两部分进行同样的操作。
  4. 直到不符合循环条件为止。
    public static void quickSort(int[] arr){
        quickSort1(arr,0,arr.length-1);
    }

    public static void quickSort(int[] arr,int s,int e){

        //1,找到递归算法的出口
        if( s >= e) {
            return;
        }

        int lo = s;
        int hi = e;

        int key = arr[lo];

        while(lo<hi){

            // 从后部分开始扫描 跳过值>= key 的
            while(lo<hi && key<=arr[hi]) hi--;

            // 将前面大的值赋给 hi
            if(lo < hi) {
                arr[lo] = arr[hi];
                arr[hi] = key;
            }

            // 从前部分开始扫描 跳过值<= key 的
            while(lo<hi && arr[lo]<=key) lo++;

            // 将前面大的值赋给 hi
            if(lo < hi) {
                arr[hi] = arr[lo];
                arr[lo] = key;
            }
        }
        // 左边继续续递归
        quickSort(arr,s, lo -1 );
        // 右边继续续递归
        quickSort(arr,lo+1, e );

    }

也可以是

public static void quickSort1(int[] arr,int s,int e){

        //1,找到递归算法的出口
        if( s >= e) {
            return;
        }

        int lo = s;
        int hi = e;

        int key = arr[lo];

        int temp;
        while(lo<hi){

            // 从后部分开始扫描 跳过值>= key 的
            while(lo<hi && key<arr[hi]) hi--;

            // 从前部分开始扫描 跳过值<= key 的
            while(lo<hi && arr[lo]<=key) lo++;

            // 将前面大的值赋给 hi
            if(lo < hi) {
                temp = arr[lo];
                arr[lo] = arr[hi];
                arr[hi] = temp;
            }
        }

        arr[s] = arr[lo];
        arr[lo] = key;

        quickSort(arr,s, lo -1 );
        quickSort(arr,lo+1, e );

    }


冒泡排序

冒泡比较简单

    public static void maoPaoSort(int[] arr){
        // 交换中间变量
        int temp;
        for(int i = 0;i<arr.length;i++){

            for(int j = i+1;j<arr.length;j++){
                // 当i位置 小于 j位置 交换
                if(arr[i]>arr[j]){
                    temp = arr[i];
                    arr[i] = arr[j];
                    arr[j] = temp;
                }
            }
        }
    }

插入排序

直接插入排序

假设第一个数是有序的用后边的数据与前边有序的数据进行比较插入到合适的位置

    public static void insertSort(int[]arr){

        int temp;
        for(int i = 0;i<arr.length;i++){

            for(int j = i;j>0;j--){

                if(arr[j-1]>arr[j]){
                    temp = arr[j-1];
                    arr[j-1] = arr[j];
                    arr[j] = temp;
                }else{
                    break;
                }
            }

        }

    }

折半插入排序

在定位时使用这般查询的方式

    public static void halfInsertSort(int[]arr){

        int temp;
        for(int i = 0;i<arr.length;i++){

            int s = 0;
            int e = i-1;

            temp = arr[i];
            while(s<=e){

                int m = (s+e) >> 1;
                if(arr[m] > arr[i]){
                    e = m - 1;
                }else{
                    s = m + 1;
                }
            }
            for(int j = i;j>s;j--){
                arr[j] = arr[j-1];
            }
            arr[s] = temp;
        }

    }

希尔排序
    public static void shellInsertSort(int[] arr){

        int l = arr.length;

        // 增量
        int d = l >> 1;

        while(d > 0){
            for(int n = d;n > 0;n--){
                for(int i = n-1;i < l;i+=d){
                    for(int j = i;j > n-1;j-=d){
                        if(arr[j-d]>arr[j]){
                            int temp = arr[j-d];
                            arr[j-d] = arr[j];
                            arr[j] = temp;
                        }else{
                            break;
                        }
                    }
                }
            }
            // 当 增量为1 时 结束
            if(d == 1) break;
            // 否则 修改增量继续
            d = d >> 1;
        }

    }

选择排序

简单选择排序

从当前位置后面一次选择最小的放在当前位置

    public static void selectSort(int[] arr){

        for(int i = 0;i<arr.length;i++){
            int k = i ;
            for(int j = i+1;j<arr.length;j++){
                if(arr[j]< arr[k]) k = j;
            }
            int temp = arr[i];
            arr[i] = arr[k];
            arr[k] = temp;
        }
    }
二元选择排序

与简单选择排序不同的是 分最大和最小两种选择同时进行

    public static void twoSelectSort(int[] arr){

        int l = arr.length;

        for(int i = 0;i<=l/2;i++){
            int min = i ;
            int max = l-1-i ;

            for(int j = i;j<l-i;j++){
                if(arr[j]< arr[min]) min = j;
                if(arr[j]> arr[max]) max = j;
            }

            // min
            int temp = arr[i];
            arr[i] = arr[min];
            arr[min] = temp;

            if(max == i){
                temp = arr[l-i-1];
                arr[l-i-1] = arr[min];
                arr[min] = temp;
            }else{
                temp = arr[l-i-1];
                arr[l-i-1] = arr[max];
                arr[max] = temp;
            }

        }
    }

堆排序
    /**
     * 堆排序
     * @param arr
     */
    public static void heapSort(int[] arr){

        // 1、循环 将0 放置为最大
        // 2、 left = 2k+1  ;   right = 2k+2;

        int len = arr.length;
        while(len >0){
            // k 的计算 总数为len
            // 如果len = 2k+1(为index) +1    k = len/2 - 1
            // 如果len = 2k+2(为index) +1    k = (int)(len/2) - 1
            int k = (len >> 1) -1;

            int temp;
            // 排序
            for(int i = k ; i >=0; i-- ){

                int l = 2*i + 1;
                int r = 2*i + 2;

                if(r+1 <= len && arr[i] < arr[r]){
                    temp = arr[i];
                    arr[i] = arr[r];
                    arr[r] = temp;
                }
                if(arr[i] < arr[l]){
                    temp = arr[i];
                    arr[i] = arr[l];
                    arr[l] = temp;
                }
            }

            temp = arr[len -1];
            arr[len-1] = arr[0];
            arr[0] = temp;

            len --;
        }

    }

归并排序

    public static void mergeSort (int [] arr ,int s,int e){

        // 1、分治策略
        // 2、开始分
        // 3、合
        if(s>=e){
            return;
        }
        int r = s + ((e - s) >> 1) + 1;

        if(s<e){
            // 左边
            mergeSort(arr,s,r-1);
            // 右边
            mergeSort(arr,r,e);
        }

        int i = s;
        int j = r;

        int[] temp = new int[e-s+1];
        int index = 0;
        while(i<r||j<=e){

            if(i<r && j<=e && arr[i] <= arr[j]){
                temp[index] = arr[i];
                i++;index++;
                continue;
            }
            if(i<r && j<=e && arr[j] <= arr[i]){
                temp[index] = arr[j];
                j++;index++;
                continue;
            }

            if(i>=r){
                temp[index] = arr[j];
                j++;index++;
                continue;
            }

            if(j>e){
                temp[index] = arr[i];
                i++;index++;
                continue;
            }

        }

        index = 0;
        while(s <= e){
            arr[s++] = temp[index++];
        }
    }

    public static void mergeSort (int [] arr){
        mergeSort(arr,0,arr.length-1);
    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值