快速排序在我看来,他是一种排序思想:(以升序为例)
1.取预排序序列中的一个数作为划分值
2.从序列中找到两个数——在序列左侧的值大的数,序列右侧的值小的数(值的大小以划分数为标准)
3.交换位置
4然后再进一步对两边数作1、2、3操作,直至成为目标序列。这1、2、3、4步操作均可以不同的方式来写,来优化。
提一下:
sort在c++的<algorithm>头文件中,模板:sort(begin,end,compare); || sort(begin, end);
数组a,从0开始存,n个数
begin为数组预排序序列首地址可为a 或string类型的数组用 s.begin() (咦,这也就是说可以选择部分位置的数来排类似sort(a+3, a+n),已验证)
end为数组预排序序列的尾地址(最后一个数的下一位)即a+n 或string类型的数组用 s.end()
compare为自定义比较函数,不写则默认为升序,否则需定义类似
bool compare(int a, int b)//(int)类型根据序列类型来定
{
return a > b;// > 号则为降序 < 为升序
}
网上还看到可以include<functional>,用里面的比较函数对象less<type>、greater<type>
升序:sort(begin,end,less<data-type>());
降序:sort(begin,end,greater<data-type>()).
参考链接:https://blog.youkuaiyun.com/zzzmmmkkk/article/details/4266888
现在进入主题——从代码层对几种排法的实现的分析:(对一些=取舍的测试)
#include<iostream>
using namespace std;
int a[100];
void qsort(int, int);
void qsort_(int, int);
void qsort_t(int, int);
int n;
int main() {
cin >> n;
for(int i = 0; i < n; ++i)
cin >> a[i];
qsort_(0, n-1);
for(int i = 0; i < n; ++i)
cout << a[i] << " ";
}
//mid取中间
void qsort(int left, int right) {
int mid = a[(left+right)/2]; //a[left+((right-left)>>1)]奇技淫巧的中间值防止left+right时加法溢出。
int i = left, j = right, temp;
do{
while(a[i] < mid) i++;//此处判断条件只能为'>' ,'<'号.
while(a[j] > mid) j--;//否则像222111这样的序列就无操作。
if(i <= j)
{ //如果去掉=,当i = j时此该条件下的执行语句i++/j--都无法执行,程序无法推进。
temp = a[i];
a[i] = a[j];
a[j] = temp;
i++;//因此若要去掉 =号,可以把i++,j--均移到if语句后面。
j--;
}
}while(i <= j);//i++,j--在if内的情况,判断条件都必须有=,否则像序列12就会无限循环。
if(left < j) qsort(left, j);
if(i < right) qsort(i, right);
}
/*
考虑一个判断语句中=的取舍问题时,须看判断语句块中的执行语句对程序的运行和推进是否有影响。
*/
//mid取中间优化
void qsort_(int left, int right) {
int mid = a[(left+right)/2];
int i = left, j = right, temp;
do{
while(a[i] < mid) i++;
while(a[j] > mid) j--;/
if(i < j) {
temp = a[i];
a[i] = a[j];
a[j] = temp;
}
i++;
j--;
}while(i < j);
if(left < j)
qsort(left, j);
if(i < right)
qsort(i, right);
}
//填坑法
void qsort_t(int l, int r) {
if(l >= r)
return;
int i = l, j = r;
int key = a[r];
while(i < j) {
while(i < j && a[i] <= key)
i++;//此处比较数值与key大小必须是<=,不然a[i]==key的情况下,i不变就造成死循环。
a[j] = a[i];//若没有=,遇到1122这样(含等值的项)的序列在两个相等的数比较时会造成死循环
while(i < j && a[j] >= key)
j--;
a[i] = a[j];
}
// while(i <= j)//无论i与j用<还是<=来判断,需有不断在递进i与j的语句在执行。(代码程序无误的角度)
// {
// while(a[i] < key)
// i++;
// if(i <= j)
// {
// a[j] = a[i];
// j--;
// }
// while(a[j] > key)
// j--;
// if(i <= j)
// {
// a[i] = a[j];
// i++;
// }
//
// }
a[i] = key;
qsort(i, r);
qsort(l, i-1);
return ;
}
最后是最近学到的多关键词排序:
void qsort(int l, int r)//多关键字快排
{
int i = l, j = r, mid1 = b[(l+r)/2], mid2 = a[(l+r)/2], t;
do
{
while(b[i] < mid1 || ((b[i] == mid1) && (a[i] < mid2)))
i++;
while(b[j] > mid1 || ((b[j] == mid1) && (a[j] > mid2)))
j--;
if(i <= j)
{
t = a[i];
a[i] = a[j];
a[j] = t;
t = b[i];
b[i] = b[j];
b[j] = t;
i++;
j--;
}
}while(i <= j);
if(l < j)
qsort(l, j);
if(i < r)
qsort(i, r);
}