快排之C语言(各种数据的排序)

关于快排的一些小问题



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;	
}

喜欢的小伙伴可以点赞哦!!!!
  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值