关于快排的一些小问题
1.快排是不稳定的,这个不稳定一个表现在其使用的时间是不确定的,最好情况(O(n))和最坏情况(O(n^2))差距太大,我们一般说的O(nlog(n))都是指的是其平均时间
2.快排是不稳定的,这个不稳定表现在如果相同的比较元素,可能顺序不一样,假设我们有这样一个序列,3,3,3,但是这三个3是有区别的,我们标记为3a,3b,3c,快排后的结果不一定就是3a,3b,3c这样的排列,所以在某些特定场合我们要用结构体来使其稳定(<6>的例子就是说明这个问题的)
3.快排的比较函数的两个参数必须都是const void *的,这个要特别注意,写a和b只是我的个人喜好,写成cmp也只是我的个人喜好.推荐在cmp里面重新定义两个指针来强制类型转换,特别是在对结构体进行排序的时候
4.快排qsort的第三个参数,那个sizeof,推荐是使用sizeof(s[0])这样,特别是对结构体,往往自己定义2*sizeof(int)这样的会出问题,用sizeof(s[0)既方便又保险
5.如果要对数组进行部分排序,比如对一个s[n]的数组排列其从s[i]开始的m个元素,只需要在第一个和第二个参数上进行一些修改:qsort(&s[i],m,sizeof(s[i]),cmp)快排既不能用于过大也不能用于过小的数据,都会影响速度
首先是手工实现C的快排(每一步都有停顿)
#include<stdio.h>
#include<stdlib.h>
int main()
{
void sort(int a[9],int left,int right);
int a[9] = {4,2,7,6,8,5,0,9,1};
for(int i = 0;i < 9;i++)
{
printf("%d ",a[i]);
}
printf("\n\n");
sort(a,0,8);
for(int i = 0;i < 9;i++) printf("%d ",a[i]);
return 0;
}
void sort(int a[9],int low,int high)
{
if(low < high)
{
int left = low,right = high;
int key = a[left];
printf("\na[right] = %d a[left] = %d key = %d right = %d left = %d "
,a[right],a[left],key,right,left); //用于输出每一步每一项,按回车即可
for(int i = 0;i < 9;i++)
{
printf("%d ",a[i]);
}
system("pause");
while(left < right)
{
while(a[right] >= key && right > left) right--;
a[left] = a[right];
printf("\na[right] = %d a[left] = %d key = %d right = %d left = %d ",
a[right],a[left],key,right,left); //用于输出每一步每一项,按回车即可
for(int i = 0;i < 9;i++) printf("%d ",a[i]);
system("pause"); //按回车继续
while(a[left] <= key && right > left) left++;
a[right] = a[left];
printf("\na[right] = %d a[left] = %d key = %d right = %d left = %d ",
a[right],a[left],key,right,left); //用于输出每一步每一项,按回车即可
for(int i = 0;i < 9;i++) printf("%d ",a[i]);
system("pause");
}
a[right] = key;
printf("\nkey = a[right] = %d right = %d \n",key,right);
sort(a,right+1,high);
sort(a,low,left-1);
}
}
下面是 stdlib.h 库中的函数
//<1>
/* qsort-int型
*/
#include<stdio.h>
#include<stdlib.h>
int cmp(const void *a,const void *b)
{
return *(int *)a - *(int *)b;
}
int main()
{
int a[1001] = {9,2,6,1,8,3,0,5,7,4};
int n = 10;
// scanf("%d",&n); //手动输入
// for(int i= 0;i < n;i++)
// {
// scanf("%d",&a[i]);
// }
qsort(a,n,sizeof(a[0]),cmp);
for(int i = 0;i < n;i++)
printf("%d\n",a[i]);
return 0;
}
//<2>
/* qsotr-double型 同 int型
*/
#include<stdio.h>
#include<stdlib.h>
int cmp(const void *a,const void *b)
{
return *(double *)a > *(double *)b ? 1:-1; //如果相同的值,直接不变换,不给 0 的情况,此情况在结构体中要使用,在这不适用
}
int main()
{
double a[100] =
{
1.3,1.0,9.3,7.3,4.5,1.4,2.5,1.0,2.1,2.6
};
int n = 10;
// scanf("%d",&n); //手动输入
// for(int i = 0;i < n;i++)
// {
// scanf("%lf",&a[i]);
// }
qsort(a,n,sizeof(a[0]),cmp);
for(int i = 0;i < n;i++)
printf("%.2lf\n",a[i]);
return 0;
}
//<3>
/* qsort-结构体
*/
#include<stdio.h>
#include<stdlib.h>
struct tran
{
double data;
int no; //加入 no 为了让快排更稳定,及让double值相等时,结构体不改变位置
};
int cmp(const void *a,const void *b)
{
struct tran *aa = (tran *)a;
struct tran *bb = (tran *)b;
if(aa->data - bb->data != 0) //其实如果 double 的值是小数,可能不会相等,但是如果"相等"则不处理即可
return (aa->data > bb->data) ? 1:-1;
else
return 0;
}
int main()
{
struct tran a[100] =
{
1,0,9,0,6,0,2,0,4,0,8,0,3,0,5,0,7,0
};
int n = 10;
//scanf("%d",&n);
// for(int i = 0;i < n;i++)
// {
// a[i].no = i+1; //用于输入第几个结构
// scanf("%lf",&a[i].data);
// }
qsort(a,n,sizeof(a[0]),cmp);
for(int i = 0;i < n;i++)
printf("第%d个为%.2lf\n",a[i].no,a[i].data);
return 0;
}
//<4>
/* qsort-字符串数组 (char a[]型)
*/
#include<stdio.h>
#include<stdlib.h>
int cmp(const void *a,const void *b) //先强制转化为静态变量即常量,无法更改
{
return *(char *)a - *(char *)b; //再强制转化为所需类型
}
int main()
{
char c[10][10] =
{
"cq",
"c",
"h",
"k",
"p",
"o",
"i",
"e",
"y",
"r"
};
qsort(c,10,sizeof(c[0]),cmp);
for(int i = 0;i < 10;i++)
printf("%s\n",c[i]);
return 0;
}
//<5>
/* qsort-字符串数组 (char *a[]型)
*/
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
int cmp(const void *a,const void *b)
{
return strcmp( *(char **)a,*( (char **)b));
}
int main()
{
char *a[100];
int n;
for(int i = 0;i < n;i++)
{
a[i] = (char *)malloc(sizeof(char *));
scanf("%s",a[i]);
}
qsort(a,n,sizeof(a[0]),cmp);
for(int i = 0;i < n;i++)
printf("%s\n",a[i]);
return 0;
}
喜欢的小伙伴可以点赞哦!!!!