七、排序-算法总结

七、排序算法

7.1 常考排序

7.1.1 快速排序

package com.gyh.reverselinkedlist;

import java.util.*;
import java.util.stream.Collectors;

/**
 * @author Gao YongHao
 * @version 1.0
 */
public class Test1 {
    public static void main(String[] args) {
        int[] nums = {2};
        quickSort(nums, 0, nums.length-1,false);
        Arrays.stream(nums).forEach(System.out::println);

    }

    /**
     * 快排
     * @param nums 原数组
     * @param left 左边界
     * @param right 右边界
     * @param isAsc 是否升序
     */
    private static void quickSort(int[] nums, int left, int right, boolean isAsc){
        if(nums == null || nums.length == 1){
            return;
        }
        int pivot = nums[left]; // 选定第一个数为中轴值
        int l = left , h = right;
        while(l < h){
            while(l<h && (isAsc == (nums[h] >= pivot))){
                h--;
            }
            nums[l] = nums[h];

            while(l<h && (isAsc == (nums[l] <= pivot))){
                l++;
            }
            nums[h] = nums[l];
        }
        nums[l] = pivot; // 摆放中轴值

        // 对左右分别再进行中轴值定位
        if(l - 1>left){
            quickSort(nums, left, l-1, isAsc);
        }
        if(h+1<right){
            quickSort(nums, h+1, right, isAsc);
        }
    }

}

7.1.2 归并排序

package com.gyh.reverselinkedlist;

import java.util.Arrays;

/**
 * @author Gao YongHao
 * @version 1.0
 */
public class Test2 {
    public static void main(String[] args) {
        int[] nums = {1,22,13,94,5};
        divide(nums, new int[nums.length], 0, nums.length-1,false);
        Arrays.stream(nums).forEach(System.out::println);
    }

    /**
     * 使用分治算法
     * @param nums 数组
     * @param temp 临时数组
     * @param left 保存左边界
     * @param right 保存右边界
     * @param isAsc 是否为升序
     */
    private static void divide(int[] nums, int[] temp, int left, int right, boolean isAsc){
        if(left>=right){
            return;
        }
        int mid = (right+left) / 2;
        divide(nums, temp, left, mid, isAsc);
        divide(nums, temp, mid+1, right, isAsc);
        merge(nums, temp, left, mid+1, right+1, isAsc);
    }

    private static void merge(int[] nums, int[] temp, int l, int r, int end, boolean isAsc){
        int length = 0;
        int start = l;
        int mid = r;
        while(l<mid&&r<end){
            if(isAsc?nums[l]<=nums[r]:nums[r]<=nums[l]){
                temp[length++] = nums[l++];
            }else{
                temp[length++] = nums[r++];
            }
        }
        while(l<mid) temp[length++] = nums[l++];
        while(r<end) temp[length++] = nums[r++];

        length = 0;
        for(int i = start;i<end;i++){
            nums[i] = temp[length++];
        }
    }
}

7.1.3 堆排序

package com.gyh.reverselinkedlist;

import java.util.Arrays;

/**
 * @author Gao YongHao
 * @version 1.0
 */
public class Test3 {
    public static void main(String[] args) {
        int[] nums = {10,28,1,5,88,17,2,17};
        heapSort(nums, false);
        Arrays.stream(nums).forEach(System.out::println);
    }

    private static void heapSort(int[] nums, boolean isAsc){
        // 对原数组初始化堆
        initHeap(nums, isAsc);
        // 只用作 nums.length-1 次调整堆
        for(int i = nums.length-1;i>0;i--){
            // 将堆顶元素放置于最后
            int temp = nums[0];
            nums[0] = nums[i];
            nums[i] = temp;
            adjustHeap(nums, 0, i-1, isAsc);
        }
    }

    // 初始化堆
    private static void initHeap(int[] nums, boolean isAsc){
        // nums.length/2-1为最后一个非叶子结点的位置
        // 从最后一个非叶子结点依次向上进行堆构建
        for(int i = nums.length/2-1;i>=0;i--){
            adjustHeap(nums, i, nums.length-1,isAsc);
        }
    }

    /**
     * 调整堆
     * @param nums 原数组
     * @param heapTopIndex 堆顶
     * @param lastIndex 最后一个元素的下标
     * @param isAsc 是否升序
     */
    private static void adjustHeap(int[] nums, int heapTopIndex, int lastIndex, boolean isAsc){
        if(heapTopIndex>=lastIndex){
            return;
        }
        // 按完全二叉树结构从最顶至最后一个元素依次进行堆构建
        //
        int heapTopData = nums[heapTopIndex];
        // 首先定位至其左子树
        for(int i = heapTopIndex*2+1;i<=lastIndex;i=i*2+1){
            // 定位满足堆条件的子树
            // 找到子树根节点的最大值对应的下标
            if(i<lastIndex && (isAsc?nums[i+1] > nums[i]:nums[i+1] < nums[i])){
                i++;
            }
            // 找到原始堆顶的最终位置
            if(isAsc?heapTopData >= nums[i]:heapTopData <= nums[i]){
                break;
            }
            // 与子树根节点交换(此处直接覆盖)
            nums[heapTopIndex] = nums[i];
            // 更新栈顶下标
            heapTopIndex = i;
        }
        // 将原始的堆顶元素放置于最终位置
        nums[heapTopIndex] = heapTopData;


    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

ModelBulider

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值