七、排序-算法总结

文章目录

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


    }
}
相关推荐
m0_631270403 分钟前
标准C++(二)
开发语言·c++·算法
沫刃起6 分钟前
Codeforces Round 972 (Div. 2) C. Lazy Narek
数据结构·c++·算法
爱coding的橙子12 分钟前
CCF-CSP认证考试准备第十五天 202303-3 LDAP
算法
QXH2000001 小时前
Leetcode—环形链表||
c语言·数据结构·算法·leetcode·链表
小灰灰爱代码2 小时前
C++——判断year是不是闰年。
数据结构·c++·算法
小灰灰爱代码2 小时前
C++——求3个数中最大的数(分别考虑整数、双精度数、长整数数的情况),用函数重载方法。
数据结构·c++·算法
爱coding的橙子4 小时前
CCF-CSP认证考试准备第十七天
数据结构·c++·算法
常某某的好奇心4 小时前
56 - I. 数组中数字出现的次数
算法
hungry12344 小时前
CF EDU 169
算法
程序猿阿伟5 小时前
《C++移动语义:解锁复杂数据结构的高效之道》
数据结构·c++·html