前言
由于博客还在施工,所以又来优快云写笔记了
https://www.ksroido.art/
下图是用模板写的一个首页,之后会写一篇教程如何做(大概不会咕咕咕)
正文
其实这个问题和下面的问题是关联的
我们以一个简单的插入排序为例子
#include <iostream>
int main() {
std::cout << "Hello, World!" << std::endl;
return 0;
}
void insertSort(int arr[],int len){
int i,j,curr;
for (int i = 1; i < len; ++i) {
curr = arr[i];
for (int j = i-1; j > 0 && arr[j]>curr ; --j) {
arr[j+1] = arr[j];
}
arr[j+1]=curr;
}
}
注意arr[j]>curr
和 j = i-1
为什么不是arr[j]<curr
和 j = 0
首先为什么j = i-1
因为插入排序需要插入, 插入需要后续移动, 从末尾开始可以减少插入移动次数
因为从头开始的话第一次移动就需要移动所以元素,从末尾开始第一次移动只需要移动一个元素, 以此类推第N次需要移动N个
然后我们已经确定了我们要从末尾开始, 这就意味着我们最初遇到的元素,在数学期望上是偏大的, 同时我们即将移动的curr
元素在数学期望上是偏小的
然后我们要明白,我们做完比较的目的是swap还是continue
如果是continue, 那么我们使用比较符号的方法应该符合数学预期, 也就是说, arr[j]>curr
如果是swap&break, 那说明现在比较的内容不符合数学预期, 所以我们需要用arr[j]<curr
另外一点是往往swap&break只做一次, 而且考虑到不符合数学预期, 所以一般主循环用符合数学预期的方式+continue, 因为break就跳出主循环了, 还需要加一个真正的循环出口点判断, 得不偿失