内存足够的情况下,寻找第k大或第k小的算法 1:递归: template<class T> T select(T a[], int l, int r, int k) { //在a[l:r]中选择第k小的元素 if (l >= r) return a[l]; int i = l, // 从左至右的游标 j = r + 1; // 从右至左的游标 T pivot = a[l]; //把左侧>=pivot的元素与右侧<=pivot的元素进行交换 while (true) { do { i = i + 1; // 在左侧寻找>=pivot的元素 } while (a[i] < pivot); do { j = j - 1; // 在右侧寻找<=pivot的元素 } while (a[j] > pivot); if (i >= j) break; Swap(a[i], a[j]); } if (j - l + 1 == k) return pivot; a[l] = a[j]; a[j] = pivot; if (j - l + 1 < k) return select(a, j+1, r, k-j+l-1); else return select(a, l, j-1, k); } template<class T> T Select(T a[], int n, int k) { //返回a[0:n-1]中第k小的元素 //假定a[n]是一个伪最大元素 if (k < 1 || k > n) throw OutOfBounds(); return select(a, 0, n-1, k); } 2:非递归: template<class T> T Select2(T a[], int n, int k) { //返回a[0:n-1]中第k小的元素 //假定a[n]是一个伪最大元素 if (k < 1 || k > n) throw OutOfBounds(); int l = 0; int r = n - 1; while (l < r) { int i = l, // 从左至右的游标 j = r + 1; // 从右至左的游标 T pivot = a[l]; //把左侧>=pivot的元素与右侧<=pivot的元素进行交换 while (true) { do { i = i + 1; // 在左侧寻找>=pivot的元素 } while (a[i] < pivot); do { j = j - 1; // 在右侧寻找<=pivot的元素 } while (a[j] > pivot); if (i >= j) break; Swap(a[i], a[j]); } if (j - l + 1 == k) return pivot; a[l] = a[j]; a[j] = pivot; if (j - l + 1 < k) { k -= j - l + 1; l = j + 1; } else { r = j - 1; } } return a[l]; }