# Lecture2 - 算法分析

本章考点:

  • 时间复杂度和空间复杂度(问答题、填空题
    • 固定部分、可变部分 不考
    • 具体细节不考
  • 时间复杂度中编译时间不算(知道就行
  • 排序算法要求掌握(注意有一个排序算法不在后面排序章节里
    • 代码是怎么样的、复杂度是怎么样的
  • 复杂度表示,掌握大 O 表示法,尽量写出 θ 表达式
    • 绝大多数考看代码写复杂度
    • 也有要求写 O (n) 复杂度代码
    • !折半查找代码!
  • 最大子序列算法翻一翻
  • 分治法思想
  • 四个算法思想前三个重要一点,动态规划不重要
  • 辗转相除法算法过程(复杂度不要求
  • 知道 Ω 复杂度、o 复杂度

# 时间复杂度、空间复杂度

编译时间不算

固定部分、可变部分 不考

# 定义

image-20230207133517920

空间复杂度:一个算法在运行过程中临时占用存储空间大小的量度,算法所使用的空间随输入规模变化的趋势。

时间复杂度:一个算法在运行过程中临时占用存储时间大小的量度,算法所使用的的时间随输入规模变化的趋势

# 排序算法

代码 + 复杂度

结合后面一章的排序

# selection sort 选择排序

image-20230207134411051

void selectionSort(int *a, int length){
  for(int i = length - 1; i > 1; i--){
    int index = i;
    int max = a[i];
    for(int j = 0; j < i; j++){
      if(max < a[j]){
        index = j;
        max = a[j];
      }
    }
    std::swap(a[i], a[index]);
  }
}
int main(){
  int arr[]{2, 4, 10, 8, 6};
  selectionSort(arr, 5);
  for(int i = 0; i < 5; i++){
    cout << arr[i] << " ";
  }
  return 0;
}

选择排序的最优时间复杂度、平均时间复杂度和最坏时间复杂度均为 O (n2)

image-20230207135244377

3(n-1)

n-1 次 swap,每次三次移动数据

# bubble sort 冒泡排序

void bubbleSort(int * a, int length){
  for(int i = 0; i < length; i++){
    for(int j = i; j < length - 1; j++){
      if(a[j] > a[j + 1]) swap(a[j], a[j + 1]);
    }
  }
}

image-20230207135436871

image-20230207140013939

# rank sort

image-20230207140508536

image-20230207140514479

image-20230207140524557

void rankSort(int* a, int len){
  int r[len];
  for(int i = 0; i < len; i++) r[i] = 0;
  for(int i = 1; i < len; i++){
    for(int j = 0; j < i; j++){
      if(a[j] <= a[i]) r[i] ++;
      else r[j] ++;
    }
  }
  for(int i = 0; i < len; i++){
    while(r[i] != i){
      int t = r[i];
      swap(a[i], a[t]);
      swap(r[i], r[t]);
    }
  }
}

image-20230207141448026

# 顺序查找

image-20230207141637273

image-20230207141642495

# 插入排序

void insertion_sort(int arr[], int len) {
  for (int i = 1; i < len; ++i) {
    int key = arr[i];
    int j = i - 1;
    while (j >= 0 && arr[j] > key) {
      arr[j + 1] = arr[j];
      j--;
    }
    arr[j + 1] = key;
  }
}
int main(){
  int arr[]{12, 4, 10, 8, 6};
  insertionSort(arr, 5);
  for(int i = 0; i < 5; i++){
    cout << arr[i] << " ";
  }
  return 0;
}
// 结果
4 12 10 8 6
4 10 12 8 6
4 8 10 12 6
4 6 8 10 12
4 6 8 10 12

image-20230207143758592

image-20230207150758497

# 符号

https://oi-wiki.org/basic/complexity/# 渐进符号的定义

image-20230207144147396

看 ppt

  • 复杂度表示,掌握大 O 表示法,尽量写出 θ 表达式
    • 绝大多数考看代码写复杂度
    • 也有要求写 O (n) 复杂度代码
    • !折半查找代码!
  • 最大子序列算法翻一翻
  • 分治法思想
  • 四个算法思想前三个重要一点,动态规划不重要
  • 辗转相除法算法过程(复杂度不要求
  • 知道 Ω 复杂度、o 复杂度