算法基础学习——快排与归并(附带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]+" ");
        }

    }
}
相关推荐
ZoeJoy817 分钟前
算法筑基(二):搜索算法——从线性查找到图搜索,精准定位数据
算法·哈希算法·图搜索算法
Alicx.22 分钟前
dfs由易到难
算法·蓝桥杯·宽度优先
_日拱一卒33 分钟前
LeetCode:找到字符串中的所有字母异位词
算法·leetcode
云泽8081 小时前
深入 AVL 树:原理剖析、旋转算法与性能评估
数据结构·c++·算法
薛先生_0991 小时前
js学习语法第一天
开发语言·javascript·学习
Wilber的技术分享2 小时前
【LeetCode高频手撕题 2】面试中常见的手撕算法题(小红书)
笔记·算法·leetcode·面试
邪神与厨二病2 小时前
Problem L. ZZUPC
c++·数学·算法·前缀和
梯度下降中3 小时前
LoRA原理精讲
人工智能·算法·机器学习
IronMurphy3 小时前
【算法三十一】46. 全排列
算法·leetcode·职场和发展
czlczl200209253 小时前
力扣1911. 最大交替子序列和
算法·leetcode·动态规划