/*************************************************************************
> File Name: test1.cpp
> Author:Xiao Yuheng
> Mail:[email protected]
> Created Time: Sat Nov 4 10:48:10 2023
************************************************************************/
#include
#include
using namespace std;
bool cmp1(int a, int b) {
return a < b;
}
bool cmp2(int a, int b) {
return a > b;
}
void __quick_sort(int *first, int *last, function cmp = less()) {
if (first >= last) return ;
int *l = first, *r = last - 1, value = *first;
while (l < r) {
while (l < r && cmp(value, *r)) r--;
if (l < r) *(l++) = *r;
while (l < r && cmp(*l, value)) l++;
if (l < r) *(r--) = *l;
}
*l = value;
__quick_sort(first, l, cmp);
__quick_sort(l + 1, last, cmp);
return ;
}
void sort(int *first, int *last, function cmp = less()) {
__quick_sort(first, last, cmp);
return ;
}
void output(int *first, int *last, const char *str) {
cout << str << " = ";
while (first < last) {
cout << *(first++) << " ";
}
cout << endl;
return ;
}
int main() {
int n, a[10020];
cin >> n;
for (int i = 0; i < n; i++) cin >> a[i];
sort(a, a + n, cmp1);
output(a, a + n, "cmp1");
sort(a, a + n, cmp2);
output(a, a + n, "cmp2");
return 0;
}
__quick_sort
函数:
cppCopy codevoid __quick_sort(int *first, int *last, function cmp = less()) {
if (first >= last) return ;
int *l = first, *r = last - 1, value = *first;
while (l < r) {
while (l < r && cmp(value, *r)) r--;
if (l < r) *(l++) = *r;
while (l < r && cmp(*l, value)) l++;
if (l < r) *(r--) = *l;
}
*l = value;
__quick_sort(first, l, cmp);
__quick_sort(l + 1, last, cmp);
return ;
}
int *first
:指向待排序范围的起始位置的指针。int *last
:指向待排序范围的结束位置的下一个位置的指针。function cmp = less()
:一个比较函数,默认为less()
,表示默认按照升序排列。first
和last
的关系,如果first >= last
,说明排序范围为空或者只有一个元素,无需进行排序,直接返回。first
指向的元素作为基准值value
。l
和r
分别指向排序范围的开始和结束位置。我们这里调用sort
函数来进行排序,现在sort
内部只有一个快速排序,我们我们接着来进行优化。
/*************************************************************************
> File Name: test1.cpp
> Author:Xiao Yuheng
> Mail:[email protected]
> Created Time: Sat Nov 4 10:48:10 2023
************************************************************************/
#include
#include
using namespace std;
bool cmp1(int a, int b) {
return a < b;
}
bool cmp2(int a, int b) {
return a > b;
}
void __quick_sort(int *first, int *last, function cmp = less()) {
while (first < last) {
int *l = first, *r = last - 1;
int value = *first;
do{
while (cmp(*l, value)) l++;
while (cmp(value, *r)) r--;
if (l <= r) swap(*(l++), *(r--));
} while (l <= r);
__quick_sort(l, last, cmp);
last = r + 1;
}
return ;
}
void sort(int *first, int *last, function cmp = less()) {
__quick_sort(first, last, cmp);
return ;
}
void output(int *first, int *last, const char *str) {
cout << str << " = ";
while (first < last) {
cout << *(first++) << " ";
}
cout << endl;
return ;
}
int main() {
int n, a[10020];
cin >> n;
for (int i = 0; i < n; i++) cin >> a[i];
sort(a, a + n, cmp1);
output(a, a + n, "cmp1");
sort(a, a + n, cmp2);
output(a, a + n, "cmp2");
return 0;
}
优化方法为单边递归和无监督优化,详细解释:【精选】十大排序算法(C++)_c++排序算法-CSDN博客
/*************************************************************************
> File Name: test1.cpp
> Author:Xiao Yuheng
> Mail:[email protected]
> Created Time: Sat Nov 4 10:48:10 2023
************************************************************************/
#include
#include
using namespace std;
bool cmp1(int a, int b) {
return a < b;
}
bool cmp2(int a, int b) {
return a > b;
}
const int threshold = 16;
void __quick_sort(int *first, int *last, function cmp = less()) {
while (last - first > threshold) {
int *l = first, *r = last - 1, value = *first;
do{
while (cmp(*l, value)) l++;
while (cmp(value, *r)) r--;
if (l <= r) swap(*(l++), *(r--));
} while (l <= r);
__quick_sort(l, last, cmp);
last = r + 1;
}
return ;
}
void insertion_sort(int *first, int *last, function cmp = less()) {
int *ind = first;
for (int *i = first + 1; i < last; i++) {
if (cmp(*i, *ind)) ind = i;
}
while (ind != first) {
swap(*ind, *(ind - 1));
ind--;
}
for (int *i = first + 2; i < last; i++) {
int *j = i;
while (cmp(*j, *(j - 1))) {
swap(*j, *(j - 1));
j--;
}
}
return ;
}
void sort(int *first, int *last, function cmp = less()) {
__quick_sort(first, last, cmp);
insertion_sort(first, last, cmp);
return ;
}
void output(int *first, int *last, const char *str) {
cout << str << " = ";
while (first < last) {
cout << *(first++) << " ";
}
cout << endl;
return ;
}
int main() {
int n, a[10020];
cin >> n;
for (int i = 0; i < n; i++) cin >> a[i];
sort(a, a + n, cmp1);
output(a, a + n, "cmp1");
sort(a, a + n, cmp2);
output(a, a + n, "cmp2");
return 0;
}
插入排序的引入:
为了提高性能,当待排序范围的大小小于 threshold
时,切换到插入排序算法。插入排序在小规模数据上比快速排序更高效,因为它的时间复杂度是 O(n^2),但是常数因子比快速排序小。
cppCopy codevoid insertion_sort(int *first, int *last, function cmp = less()) {
int *ind = first;
for (int *i = first + 1; i < last; i++) {
if (cmp(*i, *ind)) ind = i;
}
while (ind != first) {
swap(*ind, *(ind - 1));
ind--;
}
for (int *i = first + 2; i < last; i++) {
int *j = i;
while (cmp(*j, *(j - 1))) {
swap(*j, *(j - 1));
j--;
}
}
return ;
}
插入排序中也引用了无监督优化
RandomIter
迭代器/*************************************************************************
> File Name: test1.cpp
> Author:Xiao Yuheng
> Mail:[email protected]
> Created Time: Sat Nov 4 10:48:10 2023
************************************************************************/
#include
#include
using namespace std;
bool cmp1(int a, int b) {
return a < b;
}
bool cmp2(int a, int b) {
return a > b;
}
const int threshold = 16;
class RandomIter {
public:
RandomIter(int *ptr) : ptr(ptr) {}
int operator-(RandomIter &ran) { return ptr - ran.ptr; }
RandomIter operator-(int x) { return ptr - x; }
RandomIter operator+(int x) { return ptr + x; }
int &operator*() { return *ptr; }
RandomIter operator++(int) { return ptr++; }
RandomIter operator--(int) { return ptr--; }
// 运用小于号来重载 > <= >=
bool operator<(RandomIter &iter) { return ptr < iter.ptr; }
bool operator>(RandomIter &iter) { return iter < *this; }
bool operator<=(RandomIter &iter) { return !(iter < *this); }
bool operator>=(RandomIter &iter) { return !(*this < iter); }
bool operator!=(RandomIter &iter) { return (*this < iter) || (iter < *this); }
bool operator==(RandomIter &iter) { return !(*this < iter) && !(iter < *this); }
private:
int *ptr;
};
void __quick_sort(RandomIter first, RandomIter last, function cmp = less()) {
while (last - first > threshold) {
RandomIter l = first, r = last - 1;
int value = *first;
do{
while (cmp(*l, value)) l++;
while (cmp(value, *r)) r--;
if (l <= r) swap(*(l++), *(r--));
} while (l <= r);
__quick_sort(l, last, cmp);
last = r + 1;
}
return ;
}
void insertion_sort(RandomIter first, RandomIter last, function cmp = less()) {
RandomIter ind = first;
for (RandomIter i = first + 1; i < last; i++) {
if (cmp(*i, *ind)) ind = i;
}
while (ind != first) {
swap(*ind, *(ind - 1));
ind--;
}
for (RandomIter i = first + 2; i < last; i++) {
RandomIter j = i;
while (cmp(*j, *(j - 1))) {
swap(*j, *(j - 1));
j--;
}
}
return ;
}
void sort(RandomIter first, RandomIter last, function cmp = less()) {
__quick_sort(first, last, cmp);
insertion_sort(first, last, cmp);
return ;
}
void output(int *first, int *last, const char *str) {
cout << str << " = ";
while (first < last) {
cout << *(first++) << " ";
}
cout << endl;
return ;
}
int main() {
int n, a[10020];
cin >> n;
for (int i = 0; i < n; i++) cin >> a[i];
sort(a, a + n, cmp1);
output(a, a + n, "cmp1");
sort(a, a + n, cmp2);
output(a, a + n, "cmp2");
return 0;
}
RandomIter
类的运算符重载,提供了一种更面向对象的方式来处理数组元素,使代码更具面向对象编程(OOP)的特性。/*************************************************************************
> File Name: test1.cpp
> Author:Xiao Yuheng
> Mail:[email protected]
> Created Time: Sat Nov 4 10:48:10 2023
************************************************************************/
#include
#include
using namespace std;
bool cmp1(int a, int b) {
return a < b;
}
bool cmp2(int a, int b) {
return a > b;
}
const int threshold = 16;
class RandomIter {
public:
RandomIter(int *ptr) : ptr(ptr) {}
int operator-(RandomIter &ran) { return ptr - ran.ptr; }
RandomIter operator-(int x) { return ptr - x; }
RandomIter operator+(int x) { return ptr + x; }
int &operator*() { return *ptr; }
RandomIter operator++(int) { return ptr++; }
RandomIter operator--(int) { return ptr--; }
// 运用小于号来重载 > <= >=
bool operator<(RandomIter &iter) { return ptr < iter.ptr; }
bool operator>(RandomIter &iter) { return iter < *this; }
bool operator<=(RandomIter &iter) { return !(iter < *this); }
bool operator>=(RandomIter &iter) { return !(*this < iter); }
bool operator!=(RandomIter &iter) { return (*this < iter) || (iter < *this); }
bool operator==(RandomIter &iter) { return !(*this < iter) && !(iter < *this); }
private:
int *ptr;
};
int Get_mid(RandomIter first, RandomIter last) {
int a = *first;
int b = *(last - 1);
int c = *(first + ((last - first) >> 1));
if (a > b) swap(a, b);
if (a > c) swap(a, c);
if (b > c) swap(b, c);
return b;
}
void __quick_sort(RandomIter first, RandomIter last, function cmp = less()) {
while (last - first > threshold) {
RandomIter l = first, r = last - 1;
// int value = *first;
int value = Get_mid(first, last);
do{
while (cmp(*l, value)) l++;
while (cmp(value, *r)) r--;
if (l <= r) swap(*(l++), *(r--));
} while (l <= r);
__quick_sort(l, last, cmp);
last = r + 1;
}
return ;
}
void insertion_sort(RandomIter first, RandomIter last, function cmp = less()) {
RandomIter ind = first;
for (RandomIter i = first + 1; i < last; i++) {
if (cmp(*i, *ind)) ind = i;
}
while (ind != first) {
swap(*ind, *(ind - 1));
ind--;
}
for (RandomIter i = first + 2; i < last; i++) {
RandomIter j = i;
while (cmp(*j, *(j - 1))) {
swap(*j, *(j - 1));
j--;
}
}
return ;
}
void sort(RandomIter first, RandomIter last, function cmp = less()) {
__quick_sort(first, last, cmp);
insertion_sort(first, last, cmp);
return ;
}
void output(int *first, int *last, const char *str) {
cout << str << " = ";
while (first < last) {
cout << *(first++) << " ";
}
cout << endl;
return ;
}
int a[10000020];
int main() {
int n;
cin >> n;
for (int i = 0; i < n; i++) cin >> a[i];
sort(a, a + n, cmp1);
output(a, a + n, "cmp1");
sort(a, a + n, cmp2);
output(a, a + n, "cmp2");
return 0;
}
引入了 Get_mid
函数:
cppCopy codeint Get_mid(RandomIter first, RandomIter last) {
int a = *first;
int b = *(last - 1);
int c = *(first + ((last - first) >> 1));
if (a > b) swap(a, b);
if (a > c) swap(a, c);
if (b > c) swap(b, c);
return b;
}
RandomIter
对象,分别指向待排序范围的起始位置和结束位置。a <= b <= c
,返回 b
作为中值元素。value
都是有意义的。