1. 插入排序:
O(n2)
void InsertSort(int* a, int n) {
int j, k;
for (int i = 1; i < n; i ++) {
j = i - 1;
k = a[i]; //防止a[i]在下面的操作中被覆盖掉
while(j >= 0 && k < a[j]) {
a[j + 1] = a[j]; //腾出位置
j--;
}
a[j + 1] = k;
}
}
2. 归并排序:
O(nlog(n))
Merge过程:
自己实现的时候还是想在原数组上操作,但是为了避免覆盖,会增加很多额外的操作,《算法导论》里面的哨兵牌也很关键,省去了类似如下的操作:
if (i == q - 1) {
for (int k = j; k <= r; k++) {
a[p] = a[k];
p++;
}
} else if (j == r) {
for (int k = i; k < q; k++) {
a[p] = a[k];
p++;
}
}
实现代码如下:
# define MAXN 100000000
void Merge(int* a, int p, int q, int r) {
int n1 = q - p + 1;
int n2 = r - q;
int L[n1 + 1], R[n2 + 1];
for (int i = 0; i < n1; i++) {
L[i] = a[p+i];
}
for (int i = 0; i < n2; i++) {
R[i] = a[q+i+1];
}
L[n1] = R[n2] = MAXN; //哨兵牌
//for debug:
//cout << "debug\n";
//cout << "p: " << p << " q: " << q << " r: " << r << endl;
//for (int i = 0; i < n1 + 1; i ++) cout << L[i] << " ";
//cout << endl;
//for (int i = 0; i < n2 + 1; i ++) cout << R[i] << " ";
//cout << endl;
int i = 0, j = 0;
for (int k = p; k <= r; k ++) {
if (L[i] > R[j]) {
a[k] = R[j];
j++;
} else {
a[k] = L[i];
i++;
}
}
}
然后递归:
//参数表的下标要能够访问到:
//比如a[n] 传入参数为(a, 0, n-1)
void MergeSort(int* a, int p, int r) {
if (p < r) {
int q = (p + r) / 2;
MergeSort(a, p, q);
MergeSort(a, q + 1, r);
Merge(a, p, q, r);
}
}
这里的心得就是,找清楚边界值的位置太关键了。