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

目录
  • 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;
}

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

(0)

相关推荐

  • C语言实现单链表的快速排序算法

    目录 背景 设计思路 算法主要步骤 快速排序算法实现 整个程序源代码 测试案例 总结 背景 传统QuickSort算法最大不足之处在于,由于其基于可索引存储结构设计(一般为数组或索引表),因而无法用于链式存储结构,而链式存储结构的实际应用非常广泛,例如动态存储管理.动态优先级调度等等,故本文针对于单向链表,以QuickSort的分治策略为基础,提出一种可用于单向链表的快速排序算法. 设计思路 将单向链表的首节点作为枢轴节点,然后从单向链表首部的第二个节点开始,逐一遍历所有后续节点,并将这些已遍历

  • C语言中数据结构之链表归并排序实例代码

    C语言中数据结构之链表归并排序实例代码 问题 设有两个无头结点的单链表,头指针分别为ha,hb,链中有数据域data,链域next,两链表的数据都按递增排序存放,现要求将hb表归到ha表中,且归并后ha仍递增序,归并中ha表中已有的数据若hb中也有,则hb中的数据不归并到ha中,hb的链表在算法中不允许破坏. 源程序 #include <stdio.h> #include<stdlib.h> #define N1 6 /*链表La的长度*/ #define N2 6 /*链表Lb的

  • c语言实现的几种常用排序算法

    概述 最近重新回顾了一下数据结构和算法的一些基本知识,对几种排序算法有了更多的理解,也趁此机会通过博客做一个总结. 1.选择排序-简单选择排序 选择排序是最简单的一种基于O(n2)时间复杂度的排序算法,基本思想是从i=0位置开始到i=n-1每次通过内循环找出i位置到n-1位置的最小(大)值. 算法实现: void selectSort(int arr[], int n) { int i, j , minValue, tmp; for(i = 0; i < n-1; i++) { minValue

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

    目录 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 = (str

  • 浅谈Go语言中的结构体struct & 接口Interface & 反射

    结构体struct struct 用来自定义复杂数据结构,可以包含多个字段(属性),可以嵌套: go中的struct类型理解为类,可以定义方法,和函数定义有些许区别: struct类型是值类型. struct定义 type User struct { Name string Age int32 mess string } var user User var user1 *User = &User{} var user2 *User = new(User) struct使用 下面示例中user1和

  • C语言中关于库函数 qsort 快排的用法

    目录 前言 一.库函数(qsort)的含义 二.(qsort)函数的实现方式,话不多说,请看. 1. 第一个参数 2. 第二个参数 3. 第三个参数 4. 第四个参数 1). 函数的参数 2). 这第四个参数的重点 三.函数实现 四.总结 前言 我也只是一个奋斗的程序猿,仅以此篇文章,作为我学习的见证,可能我的文采不好,有时候讲的词不达意,但我尽力去做好我想做的这些事情,如果此篇文章能够给各位读者带来一定的认识,那自然是最好的.若文章中有鄙人讲错了的,欢迎评论区指点.谢谢!!! 一.库函数(qs

  • C语言中的结构体在Python中实现转换

    目录 struct介绍 struct中的常用接口 pack() unpack() fmt 示例 struct介绍 Python中提供了struct接口,用来处理类似C语言中的结构体. 处理的方式是将结构体表现位字符串,这个字符串其实就是结构体的一个个字节. struct中的常用接口 主要就是两个,pack()和unpack(). pack()就是将结构体转换成字符串(或者说字节序),unpack()则相反. pack() pack()函数的说明如下(来自Python 2.7.15 documen

  • C语言中隐藏结构体的细节

    我们都知道,在C语言中,结构体中的字段都是可以访问的.或者说,在C++ 中,类和结构体的主要区别就是类中成员变量默认为private,而结构体中默认为public.结构体的这一个特性,导致结构体中封装的数据,实际上并没有封装,外界都可以访问结构体重的字段. C++中我们尚可用类来替代结构体,但是,C语言中是没有类的,只能用结构体,但很多时候,我们需要隐藏结构体的字段,不让外界直接访问,而是通过我们写的函数进行间接访问,这样就提高了程序的封装性. 实现方法,简单来说,就是,结构体定义时,要定义在.

  • C语言中的结构体的入门学习教程

    C语言中数组允许定义类型的变量,可容纳相同类型的多个数据项,但结构体在C语言编程中,它允许定义不同种类的数据项可供其他用户定义的数据类型. 结构是用来代表一个记录,假设要跟踪图书馆的书籍.可能要跟踪有关每本书以下属性: Title - 标题 Author - 作者 Subject - 科目 Book ID - 编号 定义结构体 定义一个结构体,必须使用结构体的struct语句.该struct语句定义了一个新的数据类型,程序不止一个成员.struct语句的格式是这样的: struct [struc

  • Go语言学习函数+结构体+方法+接口

    目录 1. 函数 1.1 函数返回值 同一种类型返回值 带变量名的返回值 函数中的参数传递 函数变量 1.2 匿名函数——没有函数名字的函数 在定义时调用匿名函数 将匿名函数赋值给变量 匿名函数用作回调函数 可变参数——参数数量不固定的函数形式 1.3 闭包 1.4 defer语句 处理运行时发生的错误 1.5 宕机恢复(recover)——防止程序崩溃 2. 结构体 2.1 定义与给结构体赋值 3. 方法 3.1 结构体方法 3.2 接收器 指针接收器 非指针类型接收器 4. 接口 4.1 声

  • C语言 structural body结构体详解用法

    目录 结构体 结构体类型的声明 举个现实例子 程序实例 结构体成员的类型: 结构体变量的定义和初始化 程序一 结构体嵌套情况下,初始化和定义 结构体成员的访问 结构体传参 程序一: 程序二 结构体 结构是一些值的集合,这些值称为成员变量,结构的每个成员可以是不同类型的变量 结构体类型的声明 创建 结构体类型 没有占 内存空间,因为还 没有 创建变量 举个现实例子                 盖房子 图纸 --------------------> 房子 结构体类型        结构体变量

  • C语言 详细分析结构体的内存对齐

    目录 一.结构体 二.结构体内存对齐 1.非嵌套结构体的大小 2.含嵌套结构体的大小 三.为什么要内存对齐 1.平台原因(移植原因) 2.性能原因 一.结构体 结构体 (struct)是一种数据结构,可以包含很多数据类型,可以实现比较复杂的数据结构. 常见的int,char类型变量,我们可以一眼看出占多少字节,但对于结构体,可就有点难度了. 让我们来猜猜以下程序的输出 struct S1 { char c1; int i; char c2; }; struct S2 { char c1; cha

  • C语言详解结构体的内存对齐与大小计算

    目录 结构体的内存对齐 1.计算结构体的大小 2.结构体的对齐规则 3.为什么存在内存对齐? 4.总结 结构体的内存对齐 1.计算结构体的大小 struct S1 { char c1; // 1 byte,默认对齐数为8,所以c1的对齐数是1,第一个成员变量放在与结构体变量偏移量为0的地址处 int i; // 4 byte,默认对齐数为8,所以i的对齐数是4,所以i要放到偏移量为 4的整数倍 的地址处 char c2; // 1 byte,默认对齐数为8,所以c2的对齐数是1,所以c2要放到偏

随机推荐