当前位置: 首页 > article >正文

lec9-Sortings

lec9-Sorting 排序

1. 概述

2. 插入排序

  • 插入排序这一个大类的思想,是v0, … vi-1都插入好了,考虑 vi 插入进去

2.1. 直接插入排序

void sort(int arr[], int n){
    for(int i = 1;i < n;i++){
        int temp = arr[i];
        // 1 2 3 4 2
        for(int j = i-1; j >= 0;j--){
            if(arr[j] > temp){
                arr[j + 1] = arr[j]
            }else{
                arr[j] = temp;
                break;
            }
        }
    }
}
  • 直接插入排序的手动模拟?可能会考到
  • 算法分析部分:
    • 最好情况:已经有序,比较次数只需要 n-1,移动次数只需要 0
    • 最坏情况:刚好逆序,比较次数需要 1 + 2 +… + n - 1 = n(n-1) / 2,移动次数 n 2 + 3 n − 4 2 \frac {n^2 + 3n - 4} 2 2n2+3n4
  • 稳定性:是稳定的(手写排序的时候可以验证一下)

2.2. 折半插入排序

  • 虽然比较次数减少,但是移动次数还是 O ( n 2 ) O(n^2) O(n2)
  • 一般少用
  • 稳定性: 稳定的

2.3. 希尔排序

  • 也叫做缩小增量排序
  • 算法:取出一个增量,gap < n,按增量分组,对每组使用直接插入排序或其他方法进行排序,然后缩小增量
public static void shellsort(Comparable []a){
    for(int gap = a.length / 2;gap > 0;gap /= 2){
        for(int i = gap; i < a.length; i++){ // 这里i = gap, 实际上就相当于第 0 组 的 一号(第二个)元素,然后类似与插入排序过程
            Comparable tmp = a[i];
            int j = i;
            
            // 此处暂时略去
        }
    }
}
  • 稳定性: 不稳定
  • 平均比较次数和移动次数大约是 n 1.3 n^{1.3} n1.3

3. 交换排序

  • 方法的本质:不断地交换反序的对偶,直到不再有反序的对偶为止
  • 冒泡排序 和 快速排序

3.1. 冒泡排序

  • 冒泡排序的一个重要的特点是: 每一轮冒泡彻底完成后,必然将一个最大或最小值冒泡到最边上

  • 比较次数的问题

    • 最小比较次数: n-1 次比较,移动次数是0

    • 最大比较次数:n(n-1) / 2

  • 稳定性: 稳定的

3.2. 快速排序

  • 关键是,考虑一个基准值,让小的都放在基准值左面,大的都放在基准值右面
public int partition(int []arr, int left, int right){
    int pivot = arr[left];
    int i = left, j = right;
    while(i != j){
        while(arr[j] > pivot) j--;
        if(i < j) {arr[i] = arr[j]; i++;}
        
        while(arr[i] < pivot) i++;
        if(i < j) {arr[j] = arr[i]; j--;}
    }
    arr[i] = pivot;
    return i;
}

public void quickSort(int []arr, int left, int right){
    int mid = partition(arr, left, right);
    quickSort(arr, left, mid - 1);
    quickSort(arr, mid + 1, right);
}
  • 稳定性: 是不稳定的,比如拿最前和最后
  • 算法分析:
    • 最坏情况:当pivot第一个的时候,排好序反而复杂度是 O ( n 2 ) O(n^2) O(n2)
    • 理想情况:每次都可以定位到中间 O ( n log ⁡ n ) O(n \log n ) O(nlogn)
  • 很少要考虑空间复杂度:
    • 最坏情况: O ( n ) O(n) O(n),每次都要创建新的栈
    • 最好情况: O ( log ⁡ n ) O(\log n) O(logn),每次递归完之后都会释放的

4. 选择排序

  1. 直接选择排序
  2. 锦标赛排序(很不常用,几乎可以忽略)
  3. 堆排序
  • 选择排序里的 直接选择排序 和 堆排序都是不稳定的

4.1. 直接选择排序

  • 算法分析:比较次数 一定是 O ( n 2 ) O(n^2) O(n2),不会受到序列影响

4.2. 堆排序

  • 先初始化堆, 然后每次删除的时候就是 交换+下滤

  • 可能需要注意,堆的最值取值是 0 还是 1;对应了不同的孩子计算方法

5. 归并排序

  • 稳定性:是稳定的,这也是比较显然,因为在数组中是有前后分别的

http://www.kler.cn/a/549472.html

相关文章:

  • 【ESP32】ESP-IDF开发 | WiFi开发 | HTTPS服务器 + 搭建例程
  • 【动态规划】落花人独立,微雨燕双飞 - 8. 01背包问题
  • 【Java学习】二维数组
  • 蓝桥杯---颜色分类(leetcode第75题)题解
  • Ollama命令使用指南
  • 论文阅读_用于低频隔振的高负刚度新型阵列磁性弹簧的分析与设计_2
  • 结构型模式---代理模式
  • EasyRTC视频通话WebP2P技术:轻量化SDK助力嵌入式设备实时音视频通信
  • Vue.js 组件开发深入解析:Vue 2 vs Vue 3
  • 【漫话机器学习系列】094.交叉熵(Cross-Entropy)
  • 数据结构------单向链表。
  • 苍穹外卖day4 redis相关简单知识 店铺营业状态设置
  • Linux 基础IO——重定向和缓冲区
  • 大疆无人机需要的kml文件如何制作kml导出(大疆KML文件)
  • Instagram与小红书的自动化运营
  • Vite入门指南
  • github用户名密码登陆失效了
  • Mac上搭建宝塔环境并部署PHP项目
  • Ubuntu 连接 air pods
  • ios中常见的设计原则和设计模式