七、排序-算法总结

文章目录

  • 七、排序算法
    • [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;


    }
}
相关推荐
半盏茶香14 分钟前
扬帆数据结构算法之雅舟航程,漫步C++幽谷——LeetCode刷题之移除链表元素、反转链表、找中间节点、合并有序链表、链表的回文结构
数据结构·c++·算法
CodeJourney.34 分钟前
小型分布式发电项目优化设计方案
算法
DARLING Zero two♡1 小时前
【初阶数据结构】逆流的回环链桥:双链表
c语言·数据结构·c++·链表·双链表
带多刺的玫瑰1 小时前
Leecode刷题C语言之从栈中取出K个硬币的最大面积和
数据结构·算法·图论
Cando学算法1 小时前
Codeforces Round 1000 (Div. 2)(前三题)
数据结构·c++·算法
薯条不要番茄酱1 小时前
【动态规划】落花人独立,微雨燕双飞 - 8. 01背包问题
算法·动态规划
小林熬夜学编程1 小时前
【Python】第三弹---编程基础进阶:掌握输入输出与运算符的全面指南
开发语言·python·算法
字节高级特工1 小时前
【优选算法】5----有效三角形个数
c++·算法
秋风&萧瑟3 小时前
【数据结构】顺序队列与链式队列
linux·数据结构·windows
小孟Java攻城狮7 小时前
leetcode-不同路径问题
算法·leetcode·职场和发展