快速排序
排序方法有很多种:选择排序,冒泡排序,归并排序,快速排序等。 看名字都知道快速排序是目前公认的一种比较好的排序算法。
快速排序的核心思想是二分法。
在此,我以升序为例。
首先,我们需要选取一个基准数temp,再通过循环比较,将比基准数小的放在左边,大的放右边,然后把基准数归位。之后,用递归,将每一段二分,直到所有数都归位,此时每段左边都比右边小,完成排序。
代码如下:
#include <stdio.h>
int a[101],n;//定义全局变量,这两个变量需要在子函数中使用
void quicksort(int left, int right) {
int i, j, t, temp;
if(left > right) //终止条件
return;
temp = a[left]; //temp中存的就是基准数
i = left;
j = right;
while(i != j) { //顺序很重要,要先从右边开始找
while(a[j] >= temp && i < j)
j--;
while(a[i] <= temp && i < j)//再找右边的
i++;
if(i < j)//交换两个数在数组中的位置
{
t = a[i];
a[i] = a[j];
a[j] = t;
}
}
//最终将基准数归位
a[left] = a[i];
a[i] = temp;
quicksort(left, i-1);//继续处理左边的,这里是一个递归的过程
quicksort(i+1, right);//继续处理右边的 ,这里是一个递归的过程
}
int main() {
int i; //读入数据
scanf("%d", &n);
for(i = 1; i <= n; i++)
scanf("%d", &a[i]);
quicksort(1, n); //快速排序调用
//输出排序后的结果
for(i = 1; i < n; i++)
printf("%d ", a[i]);
printf("%d\n", a[n]);
return 0;
}
因为他速度很快,所以系统也在库里实现这个算法,便于我们的使用。 这就是qsort函数(全称quicksort)。它是ANSI C标准中提供的,其声明在stdlib.h文件中,其时间复杂度为n*log(n)。
接下来,我将介绍怎么直接调用c语言stdlib.h库中 qsort 函数。
首先,函数原型为
void qsort(void *base, size_t nitems, size_t size, int (*compare)(const void , const void))
其中
base– 指向要排序的数组的第一个元素的指针。
nitems– 由 base 指向的数组中元素的个数。
size– 数组中每个元素的大小,以字节为单位。
compare– 用来比较两个元素的函数,即函数指针(回调函数)
compare函数写法为:
int comp(const void*a,const void*b)
{
return *(int *)a - *(int *)b;//由小到大(升序)
return *(int *)b - *(int *)a;//由大到小(降序)
}
Compare 函数的返回值 |
描述 |
< 0 |
a将被排在b前面 |
0 |
a 等于 b |
> 0 |
a 将被排在b后面 |
以下是不同类型下,使用qsort的模板样例:
1)对一维数组的排序实例:
#include<stdio.h>
#include<stdlib.h>
int comp(const void*a,const void*b)
{
return *(int*)a-*(int*)b;
}
int main()
{
int i=0;
int *array;
int n;
scanf("%d",&n);
array=(int*)malloc(n*sizeof(int));
for(;i<n;i++)
{
scanf("%d",(array+i));
}
qsort(array,n,sizeof(int),comp);
for(i=0;i<n;i++)
{
printf("%d\t",array[i]);
}
return 0;
}
对一个二维数组进行排序:
int a[1000][2];
int comp(const void*a,const void*b)
{
return((int*)a)[0]-((int*)b)[0];
}
qsort(a,1000,sizeof(int)*2,comp);
其中按照a[0]的大小进行一个整体的排序,其中a[1]必须和a[0]一起移动交换。//即第一行和第二行(a[0]和a[1]分别代表第一行和第二行的首地址)。使用库函数排序的代码量并不比用冒泡排序法小,但速度却快很多。
(2)对字符串进行排序
int Comp(const void*p1,const void*p2)
{
return strcmp((char*)p2,(char*)p1);
}
int main()
{
char a[MAX1][MAX2];
initial(a);//初始化a
qsort(a,lenth,sizeof(a[0]),Comp);//lenth为数组a的长度
}
(3)按结构体中某个关键字排序(对结构体一级排序):
structNode
{
double data;
int other;
}s[100];
int Comp(const void*p1,const void*p2)
{
return(*(Node*)p2).data>(*(Node*)p1).data?1:-1;
}
qsort(s,100,sizeof(s[0]),Comp);
按结构体中多个关键字排序(对结构体多级排序)[以二级为例]:
struct Node
{
int x;
int y;
}s[100];//按照x从小到大排序,当x相等时按y从大到小排序
int Comp(const void*p1,const void*p2)
{
struct Node*c=(Node*)p1;
struct Node*d=(Node*)p2;
if(c->x!=d->x)
return c->x-d->x;
else
return d->y-c->y;
}
对结构体中字符串进行排序:
struct Node
{
int data;
char str[100];
}s[100];//按照结构体中字符串str的字典序排序
int Comp(const void*p1,const void*p2)
{
return strcmp((*(Node*)p1).str,(*(Node*)p2).str);
}
qsort(s,100,sizeof(s[0]),Comp);
此次对快速排序的讲解及应用就这些了,卑微的菜菜czp在这里感谢读者们的支持。