排序算法汇总

package class01;

/**
 * @author chencc
 * @Description 排序算法
 * @Date 2022/1/19 15:42
 */
public class Code03_Sort2 {

    //TODO 1)选择排序
    public static void selectSort(int[] arr) {
        if (arr == null || arr.length < 2) {
            return;
        }
        //0-n-1 选择一个最小值,放在0位置
        //1-n-1 选择一个最小值,放在1位置
        //2-n-1 选择一个最小值,放在2位置
        //.....
        int n = arr.length;
        for (int i = 0; i < n; i++) {
            //假设初始最小位置为i
            int minIndex = i;
            //当前i,需要i+1--n-1循环比较找出最小的位置
            for (int j = i + 1; j < n; j++) {
                minIndex = arr[minIndex] < arr[j] ? minIndex : j;
            }
            //将最小值与当前i进行对换
            swap(arr, minIndex, i);
        }
    }

    //TODO 2)冒泡排序
    public static void bubbleSort(int[] arr) {
        if (arr == null || arr.length < 2) {
            return;
        }
        //冒泡排序从0开始,两两进行比较,将最大的放到最后一位
        //0-n-1 选出最大的放到n-1
        //0-n-2 选出最大的放到n-2
        //0-n-3 选出最大的放到n-3
        //.....
        int end = arr.length;
        //i控制最外层循环最后一个
        for (int i = end - 1; i >= 0; i--) {
            //边界问题,i不能<=i,不然j+1就越界
            for (int j = 0; j < i; j++) {
                if (arr[j] > arr[j + 1]) {
                    swap(arr, j, j + 1);
                }
            }
        }
    }

    //TODO 3)插入排序
    public static void insertSort(int[] arr) {
        if (arr == null || arr.length < 2) {
            return;
        }
        //0-0 上有序
        //0-1 上有序
        //0-2 上有序
        //...
        //0-n-1 上有序
        int n = arr.length;
        //i从1开始,0-0只有一位数不用比,已经有序
        for (int i = 1; i < n; i++) {
            for (int pre = i - 1; pre >= 0 && arr[pre] > arr[pre + 1]; pre--) {
                swap(arr, pre, pre + 1);
            }
        }
    }

    //TODO 4)归并排序
    public static void mergeSort(int[] arr) {
        if (arr == null || arr.length < 2) {
            return;
        }
        //将数组一分为二
        process(arr, 0, arr.length - 1);
    }

    public static void process(int[] arr, int L, int R) {
        if (L >= R) {
            return;
        }
        //(R+L)/2
        int mid = L + ((R - L) >> 1);
        //左边递归
        process(arr, L, mid);
        //右边递归
        process(arr, mid + 1, R);
        //将数组变有序
        merge(arr, L, mid, R);
    }

    public static void merge(int[] arr, int L, int M, int R) {
        //创建一个等大小的空数组
        int[] help = new int[R - L + 1];
        //初始指针
        int i = 0;
        int p1 = L;
        int p2 = M + 1;
        while (p1 <= M && p2 <= R) {
            //数组左边有序部分,跟数组右边有序部分,进行比较,将较小的值放入help数组,然后自己的坐标+1,help坐标也+1
            //直到有一侧越界为止,及p1>M或者p2>R,跳出循环
            help[i++] = arr[p1] < arr[p2] ? arr[p1++] : arr[p2++];
        }
        //此时存在有一侧还没有遍历完
        while (p1 <= M) {
            help[i++] = arr[p1++];
        }
        while (p2 <= R) {
            help[i++] = arr[p2++];
        }
        //将help值重新覆盖arr数组
        for (int j = 0; j < help.length; j++) {
            arr[L + j] = help[j];
        }
    }

    //TODO 5)快排
    public static void quickSort(int[] arr) {
        if (arr == null || arr.length < 2) {
            return;
        }
        quickProcess(arr, 0, arr.length - 1);
    }

    public static void quickProcess(int[] arr, int L, int R) {
        if (L >= R) {
            return;
        }
        //获取等于区域的坐标
        int[] equalE = partition(arr, L, R);
        //数组等于p左边部分递归
        quickProcess(arr, L, equalE[0] - 1);
        //数组等于p右边部分递归
        quickProcess(arr, equalE[1] + 1, R);
    }

    //当前数<p,当前数与<区下一位交换,<区右扩,当前数跳下一位
    //当前数=p,当前数跳下一位
    //当前数>p,当前数与>区前一位交换,>区左扩,指针不变
    public static int[] partition(int[] arr, int L, int R) {
        int lessLeft = L - 1;
        int moreRight = R;
        int index = L;
        while (index < moreRight) {
            if (arr[index] < arr[R]) {
                swap(arr, ++lessLeft, index++);
            } else if (arr[index] > arr[R]) {
                swap(arr, --moreRight, index);
            } else {
                index++;
            }
        }
        //所有的数遍历比较完成,将p值与当前>区位置数进行对换
        swap(arr, moreRight, R);
        return new int[]{lessLeft + 1, moreRight};
    }

    //对换
    private static void swap(int[] arr, int i, int j) {
        int temp = arr[i];
        arr[i] = arr[j];
        arr[j] = temp;
    }

    //打印数组
    private static void printArray(int[] arr) {
        for (int i = 0; i < arr.length; i++) {
            System.out.print(arr[i] + " ");
        }
        System.out.println();
    }

    public static void main(String[] args) {
        int[] a = {9, 3, 5, 7, 1, 0, 4, 6, 3, 8, 3, 7, 4};
        printArray(a);
        quickSort(a);
        printArray(a);
    }
}

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值