七、排序-算法总结

文章目录

  • 七、排序算法
    • [7.1 常考排序](#7.1 常考排序)
      • [7.1.1 快速排序](#7.1.1 快速排序)
      • [7.1.2 归并排序](#7.1.2 归并排序)
      • [7.1.3 堆排序](#7.1.3 堆排序)

七、排序算法

7.1 常考排序

7.1.1 快速排序

java 复制代码
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 归并排序

java 复制代码
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 堆排序

java 复制代码
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;


    }
}
相关推荐
aramae3 小时前
MySQL复合查询(8)
java·c语言·开发语言·后端·算法
荆棘鸟智能4 小时前
城市感知设备怎么统一接入?从多协议网关到设备模型的中间件架构设计
人工智能·算法·边缘计算
淡海水4 小时前
13-04-面试-源码级深度追问链
数据结构·unity·面试·c#·游戏引擎·源码·il2cpp
Logic1015 小时前
C语言/数据结构位运算题解:异或XOR找出时尚聚会中的“独特颜色“——只出现一次的数字
c语言·数据结构·数组·位运算·时间复杂度·算法题·异或性质
INGNIGHT8 小时前
270 · 电话号码的字母组合II(Trie)
linux·算法
2401_839080548 小时前
C++常见八股
数据结构·c++·算法
青山是哪个青山8 小时前
LeetCode 188:买卖股票的最佳时机 IV
算法
暮雨封夕9 小时前
跳表(Skip List)详解:原理、实现、使用场景与实际应用
数据结构
mikuyyds9 小时前
geo-toolbox 插件算法解析:RUSLE 与 MUSLE 的工程化落地
算法·rust·gis
a187927218319 小时前
【算法】树(二):队列与祖先——BFS 骨架三配件、短路透传与合流
算法·leetcode·二叉树··bfs·算法讲解·树遍历