It is amazing!列排序算法看起来很奇怪,但是它真的可以用来对所有数据排序,只不过需要有一些条件。
列排序算法是用于包含n个元素的矩形数组的排序,这个数组r行s列,满足下面三个条件:
1) r为偶数
2) s为r的因子
3) r大于等于2s2
这里就不去证明这个算法的正确性,证明见算法导论思考题8-7。感觉对于矩阵的问题,很多人第一反应会是 int a[M][N],或者使用int **a。
其实矩阵是一种数据表现形式,类似于最大最小堆,树结构一样,底层上并不是真正在对具象化的图形结构进行涂改(不像你在纸上画出来的结构),而是在一个连续的数组或者是零散的一些位置上执行操作,其效果就像是对上述的数据结构进行操作一样,是一种抽象。(轻喷 - -.) 所以这里用一个数组来表示矩阵发现代码很简洁,每一列是连续的,方便排序。
#include <iostream> #include <algorithm> using namespace std; typedef size_t row; typedef size_t column; bool Check_Ok(row r, column s); void Column_Sort(int *a, row r, column s); void Column_Sort(int *a, row r, column s){ //Check_Ok(r, s); 为了使用书上的例子,先不检查 int n = r*s; int *p = new int[n]; //step 1 for (int i = 0; i < s; ++i) { sort(a + i*r, a + i*r + r); } //step 2 for (int i = 0; i < n; ++i) { p[(i%s)*r + i / s] = a[i]; } //step 3 for (int i = 0; i < s; ++i) { sort(p + i*r, p + i*r + r); } //step 4 for (int i = 0; i < n; ++i) { a[(i%r)*s + i / r] = p[i]; } //step 5 for (int i = 0; i < s; ++i) { sort(a + i*r, a + i*r + r); } //step 6 for (int i = 0; i < s - 1; ++i) { sort(a + i*r + r / 2, a + i*r + r + r / 2); } } bool Check_Ok(row r, column s){ if (r % 2 == 1){ cout << "rows must be an even" << endl; exit(0); } if (!(r%s == 0)){ cout << "column error" << endl; exit(0); } if (r < 2 * s*s){ cout << "s too big"; exit(0); } } int main(){ int a[18] = { 10, 8, 12, 16, 4, 18, 14, 7, 1, 9, 15, 3, 5, 17, 6, 11, 2, 13 }; Column_Sort(a, 6, 3); for (auto r : a) cout << r<<" "; }