算法基础学习——快排与归并(附带java模版)

快速排序和归并排序是两种速度较快的排序方式,是最应该掌握的两种排序算法,

(一)快速排序(不稳定的)

基本思想:分治

平均时间复杂度:O(nlogn) / 最慢O(n^2) / 最快O(n)

步骤:
  • 1.确定分界点;

  • 2.调整区间;(分界点右的元素全都小于等于分界点、左边全都大于等于分界点)

  • 3.递归的处理左右两段;

模板:
java 复制代码
public static int[] quickSort(int[] arr,int l,int r){
        if(l>=r){
            return arr;
        }
        int k = arr[l+r >> 1],i=l-1,j=r+1;
        while(i<j){
            while(arr[++i]<k);
            while(arr[--j]>k);
            if(i<j){
                int temp = arr[i];
                arr[i]=arr[j];
                arr[j]=temp;
            }
        }
        quickSort(arr,l,j);
        quickSort(arr,j+1,r);
​
        return arr;
    }
​
    //TODO: 至少默写3-5遍(当前写了1遍)
    public static void main(String[] args) {
        int[] arr01 = {0,1};
        int[] arr02 = {1,2};
        int[] arr03 = {45, 78, 12, 67, 34, 90, 23, 56, 10};
​
        Scanner in = new Scanner(System.in);
        int n = in.nextInt();
        int[] arr04 = new int[n];
        for(int i=0;i<n;i++) {
            int num = in.nextInt();
            arr04[i] = num;
        }
        int[] res = quickSort(arr04, 0, n-1);
        System.out.println(Arrays.toString(res));
    }

注意点:

  • 注意i和j的初始值为:int i=l-1,j=r+1

  • 分界点k=arr[l+r >> 1]; 右移一位相当于除以二,右移2位是除以4;

(二)归并排序(稳定的)

基本思想:分治、从整个数组的中间开始划分

时间复杂度:稳定的O(nlogn)

步骤:
  1. 确定分界点mid = l+r >> 1;

  2. 递归排序左边和右边

  3. 归并(把两个有序数组合并为一个有序数组)

模板:
java 复制代码
import java.util.*;

public class Main{

    public static void mergeSort(int[] arr,int l,int r){
        //1.递归终止条件
        if(r<=l)return;

        //2.划分
        int mid = l+r>>1;
        mergeSort(arr,l,mid);
        mergeSort(arr,mid+1,r);

        //3.归并
        int tem[] = new int[r-l+1];
        int k=0,i=l,j=mid+1;
        while(i<=mid && j<=r){
            if(arr[i]<arr[j]) tem[k++] = arr[i++];
            else tem[k++] = arr[j++];
        }

        while(i<=mid) tem[k++] = arr[i++];
        while(j<=r) tem[k++] = arr[j++];

        //将临时数组中已经排好序的数据放到原数组(这里重复利用了之前定义过的i和j)
        for(i=l,j=0;i<=r;i++,j++){
            arr[i]=tem[j];
        }


    }

    public static void main(String[] args){

        Scanner in = new Scanner(System.in);

        int n = in.nextInt();
        int[] arr = new int[n];
        for(int i=0;i<n;i++){
            int num = in.nextInt();
            arr[i] = num;
        }

        mergeSort(arr,0,n-1);

        for(int i=0; i<n;i++){
            System.out.print(arr[i]+" ");
        }

    }
}
相关推荐
边跑边掩护1 分钟前
LeetCode 648 单词替换题解
算法·leetcode·职场和发展
小森776738 分钟前
(七)深度学习---神经网络原理与实现
人工智能·深度学习·神经网络·算法
charlie11451419140 分钟前
内核深入学习3——分析ARM32和ARM64体系架构下的Linux内存区域示意图与页表的建立流程
linux·学习·架构·内存管理
threelab1 小时前
03.three官方示例+编辑器+AI快速学习webgl_animation_multiple
人工智能·学习·编辑器
迷茫不知归路1 小时前
操作系统实验习题解析 上篇
c++·算法·操作系统·实验课设
threelab1 小时前
18.three官方示例+编辑器+AI快速学习webgl_buffergeometry_points_interleaved
学习·编辑器·webgl
电子云与长程纠缠1 小时前
UE5中制作动态数字Decal
学习·ue5·编辑器·贴图
愚润求学1 小时前
【递归、搜索与回溯】专题一:递归(二)
c++·笔记·算法·leetcode
h汉堡1 小时前
C/C++内存管理
java·c语言·开发语言·c++·学习
水水沝淼㵘2 小时前
嵌入式开发学习日志(数据结构--顺序结构单链表)Day19
linux·服务器·c语言·数据结构·学习·算法·排序算法