C语言中的结构体快排算法

 更新时间:2022年11月11日 12:11:52   作者:王睿丶  
这篇文章主要介绍了C语言中的结构体快排算法,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教

C语言结构体快排算法

代码:

#include<stdio.h>
#include<string.h>
#include<stdlib.h>
struct Stu{
	char name[100];	//名字 
	char xue[100];	//学号 
	int c;			//成绩 
}stu[10010];
int comp(const void* a,const void* b)
{
	struct Stu *aa = (struct Stu *)a;
	struct Stu *bb = (struct Stu *)b;
	return ((aa->c)-(bb->c));		//aa->c为结构体的成员,bb->c也为结构体的成员 
}
int main()
{
	int n;
	int i,j;
	scanf("%d",&n);
	getchar();
	for(i=0;i<n;i++)
	{
		scanf("%s%s%d",&stu[i].name,&stu[i].xue,&stu[i].c);
	}
	printf("\n");
	qsort(stu,n,sizeof(stu[0]),comp);	//参数1:结构体数组名,个数,首地址的字符数,自定义比较函数名 
	for(i=0;i<n;i++)
	printf("%s %s %d\n",stu[i].name,stu[i].xue,stu[i].c);
	return 0;
}

基于结构体数组的快速排序

用普通的数组快速排序,改造成任意数据的排序,比如结构体数组、链表、栈的排序等。只需要在排序中调用自己的compare函数,在其中把想要排序的值做一个比较即可,代码如下:

#include <stdio.h>
#include <strings.h>

typedef int (*Z_COMPARE)(void* obj1, int obj1size, void* obj2, int obj2size);
typedef struct
{
	char name[20];
	char brief_name[20];
	char desc[20];
}ROOM_INFO;

int room_info_cmp(void* obj1, int obj1size, void* obj2, int obj2size)
{
	ROOM_INFO* item1 = (ROOM_INFO*)obj1;
	ROOM_INFO* item2 = (ROOM_INFO*)obj2;
	
	if(atoi(item1->brief_name) < atoi(item2->brief_name))
	{
		return 1;
	}
	else if(atoi(item1->brief_name) > atoi(item2->brief_name))
	{
		return 0;
	}
	return -1;
}

int quicksort(ROOM_INFO* room_info, int left, int right, Z_COMPARE cmp)
{
	ROOM_INFO tmp = {0};
	ROOM_INFO f = {0};
	int rtemp,ltemp;
	
	ltemp = left;
	rtemp = right;
	if(ltemp >= rtemp)
	{
		return 0;//排序结束 
	}
	memcpy(&f, &room_info[left], sizeof(ROOM_INFO));//保存基准值
	
	while(ltemp < rtemp)
	{
		while(cmp(&room_info[rtemp], sizeof(ROOM_INFO), &f, sizeof(ROOM_INFO)) == 0 && ltemp < rtemp)
		{
			--rtemp;
		}
		if(ltemp != rtemp)
		{
			memcpy(&room_info[ltemp], &room_info[rtemp], sizeof(ROOM_INFO));
			ltemp++;
		}
		while(cmp(&room_info[ltemp], sizeof(ROOM_INFO), &f, sizeof(ROOM_INFO)) == 1 && ltemp < rtemp)
		{
			++ltemp;
		}
		if(ltemp != rtemp)
		{
			memcpy(&room_info[rtemp], &room_info[ltemp], sizeof(ROOM_INFO));
			rtemp--;
		}
	}
	memcpy(&room_info[ltemp], &f, sizeof(ROOM_INFO));

	if(left < rtemp)
	{
		quicksort(room_info, left, ltemp-1, cmp);
	}
	if(ltemp < right)
	{
		quicksort(room_info, rtemp+1, right, cmp);
	}
	return 0;
}

int main()
{
	ROOM_INFO room_info[10] = {0};
	int i = 0;
	srand(time(NULL));
	for(i = 0; i < 10; i++)
	{
		snprintf(room_info[i].brief_name, sizeof(room_info[i].brief_name), "%d", rand()%100);
	}
	
	for(i = 0; i < 10; i++)
	{
		printf("111111,room_info[%d].brief_name=%s\n",i, room_info[i].brief_name);
	}
	printf("\n\n"); 
	quicksort(room_info, 0, 9, room_info_cmp);
	for(i = 0; i < 10; i++)
	{
		printf("222222,room_info[%d].brief_name=%s\n",i, room_info[i].brief_name);
	}
	return 0;
}

运行结果如下:

如果是链表的排序,只需要把quicksort函数的第一个参数换成链表的指针,然后在排序中换成相应获取链表里的数据即可。

另外,C语言提供一个库函数,已经封装好了快速排序的算法:

void qsort(
    void *base,
    size_t nmemb,
    size_t size,
    int (*compar)(const void *, const void *)
    );

具体的信息如下:Copy from baidu

  • 参数base - base指向数组的起始地址,通常该位置传入的是一个数组名
  • 参数nmemb - nmemb表示该数组的元素个数
  • 参数size - size表示该数组中每个元素的大小(字节数)
  • 参数(*compar)(const void *, const void *) - 此为指向比较函数的函数指针,决定了排序的顺序。

函数返回值:无

注意:如果两个元素的值是相同的,那么它们的前后顺序是不确定的。也就是说qsort()是一个不稳定的排序算法。

compar参数

  • compar参数指向一个比较两个元素的函数。比较函数的原型应该像下面这样。
  • 注意两个形参必须是const void *型,同时在调用compar 函数(compar实质为函数指针,这里称它所指向的函数也为compar)时,
  • 传入的实参也必须转换成const void *型。在compar函数内部会将const void *型转换成实际类型,见下文。

int compar(const void *p1, const void *p2);

  • 如果compar返回值小于0(< 0),那么p1所指向元素会被排在p2所指向元素的前面
  • 如果compar返回值等于0(= 0),那么p1所指向元素与p2所指向元素的顺序不确定
  • 如果compar返回值大于0(> 0),那么p1所指向元素会被排在p2所指向元素的后面

因此,如果想让qsort()进行从小到大(升序)排序,那么一个上面的compar函数可以写成这样:

int room_info_cmp(void* obj1, void* obj2)
{
	ROOM_INFO* item1 = (ROOM_INFO*)obj1;
	ROOM_INFO* item2 = (ROOM_INFO*)obj2;
	
	if(atoi(item1->brief_name) < atoi(item2->brief_name))
	{
		return -1;
	}
	else if(atoi(item1->brief_name) > atoi(item2->brief_name))
	{
		return 1;
	}
	return 0;
}

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

相关文章

  • C++常用语句简介

    C++常用语句简介

    这篇文章主要介绍了C++常用语句简介,文章将要介绍的常用语句有声明变量、赋值语句、cin、cout语句、库函数、自定义函数,需要的朋友可以参考一下,希望对你有所帮助
    2021-11-11
  • c语言获取用户输入字符串是scanf和gets的区别详解

    c语言获取用户输入字符串是scanf和gets的区别详解

    今天小编就为大家分享一篇c语言获取用户输入字符串是scanf和gets的区别详解,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2018-07-07
  • C++设计模式中控制反转与依赖注入浅析

    C++设计模式中控制反转与依赖注入浅析

    这篇文章主要介绍了C++设计模式中控制反转与依赖注入,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习吧
    2023-01-01
  • C语言全面细致精讲操作符的使用

    C语言全面细致精讲操作符的使用

    C 语言提供了丰富的操作符,有:算术操作符,移位操作符,位操作符,赋值操作符,单目操作符,关系操作符,逻辑操作符,条件操作符等。接下了让我们详细了解掌握它
    2022-05-05
  • Vc++ 控件List Control用法总结

    Vc++ 控件List Control用法总结

    这篇文章主要介绍了Vc++ 控件List Control用法总结的相关资料,需要的朋友可以参考下
    2015-06-06
  • C++实现简单通讯录系统

    C++实现简单通讯录系统

    这篇文章主要为大家详细介绍了C++实现简单通讯录系统,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2022-06-06
  • 基于curses库实现弹球游戏

    基于curses库实现弹球游戏

    这篇文章主要为大家详细介绍了基于curses库实现弹球游戏,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2020-03-03
  • C语言实现24点游戏计算器的示例代码

    C语言实现24点游戏计算器的示例代码

    24点是一种益智游戏,24点是把4个整数(一般是正整数)通过加减乘除以及括号运算,使最后的计算结果是24的一个数学游戏,24点可以考验人的智力和数学敏感性,它能在游戏中提高人们的心算能力。本文将用C语言实现这一游戏,感兴趣的可以了解一下
    2022-08-08
  • C++中如何实现回调的方法示例

    C++中如何实现回调的方法示例

    这篇文章主要给大家介绍了关于C++中如何实现回调的相关资料,文中通过示例代码介绍的非常详细,对大家学习或者使用c++具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧。
    2017-10-10
  • c语言中enum类型的用法案例讲解

    c语言中enum类型的用法案例讲解

    这篇文章主要介绍了c语言中enum类型的用法案例讲解,本篇文章通过简要的案例,讲解了该项技术的了解与使用,以下就是本文的详细内容,需要的朋友可以参考下
    2021-07-07

最新评论