排序算法-选择排序|交换排序|插入排序|归并排序

本文详细介绍了几种常见的IT排序算法,包括选择排序(简单选择排序),堆排序,快速排序,插入排序(直接插入排序和希尔排序),以及归并排序,展示了它们的实现过程和关键代码片段。
摘要由CSDN通过智能技术生成
public static void selectionSort(int[] arr) {
        if (arr == null || arr.length <= 0)
            return;
        heapSort(arr);
        // simpleSelectSort(arr);
    }

    // 简单选择排序 从待排序中选择最值放入已排序部分末尾
    public static void simpleSelectSort(int[] arr) {
        // 代表已排序部分最后一个数
        int end = -1;
        // 未排序部分第一个数
        int start = 0;
        for (; start < arr.length; start++) {
            int min = start;
            for (int j = start + 1; j < arr.length; j++) {
                min = arr[min] > arr[j] ? j : min;
            }
            swap(arr, min, ++end);
        }
    }

    public static void swap(int[] arr, int i, int j) {
        int tmp = arr[i];
        arr[i] = arr[j];
        arr[j] = tmp;
    }


    // 堆排序
    public static void heapSort(int[] arr) {
        // 构建大根堆(如果最终是求的递增序列)
        buildHeap(arr);
        // 交换堆顶和末尾,然后重新构建大根堆(注意大根堆范围缩小了)
        int i = arr.length-1;
        while (i>0){
            swap(arr,0,i--);
            down(arr,0,i);
        }
    }

    public static void buildHeap(int[] arr) {
        // PC
        for (int i = arr.length - 1; i >= 0; i--) {
            down(arr, i, arr.length - 1);
        }
    }

    // end 可以达到的最后一个位置
    public static void down(int[] arr, int index, int end) {
        int parent = index;
        int child = 2 * parent + 1;
        while (child <= end) {
            child = child + 1 <= end && arr[child + 1] > arr[child] ? child + 1 : child;
            if (arr[parent] > arr[child]) {
                break;
            }
            swap(arr, parent, child);
            parent = child;
            child = parent * 2 + 1;
        }
    }

题目:交换排序

public static void exchangeSort(int[] arr) {
        if(arr == null || arr.length <= 1)
            return;
        //bubbleSort(arr);
        fastSort(arr);
    }
    public static void bubbleSort(int[] arr){
        int end = arr.length-1;
        while (end>0){
            // 每次将最大移动到末尾
            for (int i = 0;i<end;i++){
                if(arr[i] > arr[i+1]){
                    swap(arr,i,i+1);
                }
            }
            end--;
        }
    }


    public static void swap(int[] arr, int i, int j) {
        int tmp = arr[i];
        arr[i] = arr[j];
        arr[j] = tmp;
    }

    public static void fastSort(int[] arr){
        process(arr,0,arr.length-1);
    }
    // 将待排序部分划分为更小部分
    public static void process(int[] arr,int start,int end){
        if(start>=end)
            return;
        int index = start + ((int)(Math.random()*(end-start+1)));
        int piv = arr[index];
        int[] pivort = pivort(arr, start, end,piv);
        process(arr,start,pivort[0]-1);
        process(arr,pivort[1]+1,end);
    }
    // 将指定范围数组划分为三个部分,左边小于piv 中间等于 右边大于 返回等于piv的范围
    public static int[] pivort(int[] arr,int start,int end,int piv){
        // 代表小于piv最后一个元素下标
        int less = start -1;
        // 代表大于piv部分第一个元素下标
        int more = end+1;
        int cur = start;
        while (cur<more){
            if(arr[cur] == piv){
                cur++;
            }else if (arr[cur] < piv){
                ++less;
                swap(arr,cur,less);
                cur++;
            }else {
                -- more;
                swap(arr,cur,more);
            }
        }
        return new int[]{less+1,more-1};
    }

题目:插入排序

// 直接插入排序
    // 未排序部分首个元素,直接插入已排序部分
    public static void directInsertSort(int[] arr){
        if(arr == null || arr.length <=1)
            return;
        int cur = 1;
        while (cur<arr.length){
            int tmp = arr[cur];
            int pre = cur-1;
            while (pre  >=0 && arr[pre] >tmp ){
                swap(arr,pre,pre+1);
                pre--;
            }
            arr[pre+1] = tmp;
            cur++;
        }
    }

    public static void shellSort(int[] arr){
        // PC
        int offset = arr.length>>1;
        while (offset >= 1){
            for (int i = 0; i < offset; i++) {
                // i 为当前已排序部分最后一个
                // next 为未排序部分第一个
                int next = i+offset;
                while (next < arr.length){
                    int pre = next-offset;
                    int tmp = arr[next];
                    while (pre>=0 && arr[pre] > tmp ){
                        swap(arr,pre,pre+offset);
                        pre -= offset;
                    }
                    arr[pre+offset] = tmp;
                    next += offset;
                }
            }
            offset >>= 1;
        }
    }

题目:归并排序

// 归并排序
// 递归将待排序数组划分为更小部分,直到长度为1直接返回,调用方将已排序子数组合并为递增数组
    public static void mergeSort(int[] arr){
        if (arr == null || arr.length<=1)
            return;
        process(arr,0,arr.length-1);
    }
    // 将待排序数组范围划分为更小的部分
    public static void process(int[] arr,int start,int end){
        if(start >= end)
            return;
        int mid = start +((int)(Math.random()*(end-start+1)));
        process(arr,start, mid);
        process(arr,mid+1,end);
        merge(arr,start,mid,end);
    }
    // 将mid分界的两个部分合并为一个有序的
    public static void merge(int[] arr,int start,int mid,int end){
        int[] help  = new int[end - start + 1];
        int index = 0;
        int p1= start;
        int p2 = mid+1;
        while (p1<=mid && p2<=end){
            while (p1<=mid && arr[p1] <= arr[p2]){
                help[index++] = arr[p1++];
            }
            while (p2<=end && arr[p2] <= arr[p1]){
                help[index++] = arr[p2++];
            }
        }
        while (p2<=end){
            help[index++] = arr[p2++];
        }
        while (p1 <= mid){
            help[index++] = arr[p1++];
        }
        index = 0;
        while (index < help.length){
            arr[start+index] = help[index];
            index++;
        }
    }
  • 8
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值