使用一个函数实现快排

本文介绍了一种新的快速排序算法实现方法,代码简洁且易于理解,仅需十行即可完成。该方法通过递归对小于和大于基准值的元素进行排序,尽管其内存占用相对较大,但提供了一个清晰的教学示例。

在研究算法的时候发现了一种新的快排实现方法,相较于其它方法,这种方法的代码更为简洁,而且易于理解,只需要使用不到十行代码就能够实现,具体代码如下。

def quicksort(a_list):
    if len(a_list) < 2:      # 首先判断列表的长度,如果列表的长度位0或1则无需排序直接返回
        return a_list
    else:
        key = a_list[0]        # 取列表第一个值作为参照
        small = [i for i in a_list if i <= key]        # 小于key的值放到small列表中
        big = [i for i in a_list if i > key]        # 大于key的值放到big列表中
        return quicksort(small) + [key] + quicksort(big)        # 利用递归,对small和key两个列表进行快速排序,然后进行拼接
print(quicksort([5, 4, 3, 2, 1]))
# [1, 2, 3, 4, 5]

个人认为这种方法虽然简介,但是相对与其它方法对内存的占用较大。

<think>我们正在讨论C语言中使用qsort函数对结构体数组进行快速排序方法。 根据引用[3]和[4],qsort函数的声明为: void qsort(void *base, size_t nitems, size_t size, int (*compar)(const void *, const void*)); 其中: base: 待排序数组的首元素指针(地址) nitems: 数组中待排序的元素个数 size: 每个元素的大小(字节数) compar: 比较函数的指针,该函数用来比较两个元素的大小 对于结构体数组,我们需要自定义比较函数(compar),该函数接收两个const void*类型的参数(指向数组中两个待比较元素的指针),并返回一个整数: 若返回值<0,表示第一个元素应排在第二个元素前面; 若返回值=0,表示两个元素相等(顺序无关紧要); 若返回值>0,表示第一个元素应排在第二个元素后面。 在比较函数内部,我们需要将void*指针转换为结构体指针,然后访问结构体的成员进行比较。 引用[4]中给出了两个例子:按年龄排序和按名字排序。 步骤: 1. 定义结构体类型。 2. 根据排序需求编写比较函数(例如按结构体的某个成员排序)。 3. 调用qsort函数,传入数组、元素个数、元素大小和比较函数。 注意:比较函数的编写必须保证逻辑正确,满足严格弱序。 下面我们用一个完整的例子来说明: 假设有一个结构体Student,包含学生姓名(字符串)和分数(整数)。我们想按分数从高到低排序,如果分数相同,则按姓名字典序升序排序(字典序小的在前)。 </think>### C语言使用qsort函数实现结构体快速排序方法 在C语言中,`qsort`函数是标准库提供的通用排序函数,通过自定义比较函数可以实现对结构体数组的高效排序。以下是详细步骤: --- #### 1. **定义结构体类型** 首先定义需要排序的结构体类型: ```c struct Student { char name[20]; int id; float score; }; ``` --- #### 2. **编写比较函数** 比较函数负责定义排序规则,其原型必须为: ```c int compare(const void *a, const void *b); ``` 根据排序需求实现不同规则: **场景1:按单个字段排序(如分数降序)** ```c int compare_score(const void *a, const void *b) { const struct Student *s1 = (struct Student *)a; const struct Student *s2 = (struct Student *)b; return (s2->score > s1->score) ? 1 : -1; // 分数降序 } ``` **场景2:多字段排序(先按分数降序,再按姓名字典序升序)** ```c int compare_multi(const void *a, const void *b) { const struct Student *s1 = (struct Student *)a; const struct Student *s2 = (struct Student *)b; // 先比较分数 if (s1->score != s2->score) return (s2->score > s1->score) ? 1 : -1; // 分数相同时比较姓名 return strcmp(s1->name, s2->name); // 姓名字典序升序 } ``` --- #### 3. **调用qsort函数** 使用以下参数调用`qsort`: ```c struct Student students[100]; size_t count = 100; // 实际元素个数 // 单字段排序 qsort(students, count, sizeof(struct Student), compare_score); // 多字段排序 qsort(students, count, sizeof(struct Student), compare_multi); ``` 参数说明: - `students`:结构体数组首地址 - `count`:元素个数 - `sizeof(struct Student)`:单个元素大小 - `compare_score/multi`:比较函数指针 --- #### 4. **排序示例** ```c #include <stdio.h> #include <stdlib.h> #include <string.h> struct Student { char name[20]; float score; }; int compare_score(const void *a, const void *b) { return ((struct Student*)b)->score - ((struct Student*)a)->score; } int main() { struct Student list[3] = { {"Alice", 85.5}, {"Bob", 92.0}, {"Charlie", 78.5} }; qsort(list, 3, sizeof(struct Student), compare_score); for (int i = 0; i < 3; i++) { printf("%s: %.1f\n", list[i].name, list[i].score); } /* 输出: Bob: 92.0 Alice: 85.5 Charlie: 78.5 */ return 0; } ``` --- #### 关键注意事项 1. **比较函数返回值逻辑**: - 返回 **负数**:`a` 应排在 `b` 之前 - 返回 **正数**:`a` 应排在 `b` 之后 - 返回 **0**:两者相等[^4] 2. **指针类型转换**: ```c const struct Student *s = (struct Student *)ptr; ``` 必须将`void*`显式转换为结构体指针才能访问成员[^4] 3. **字符串比较**: 字典序排序需用`strcmp()`函数: ```c return strcmp(s1->name, s2->name); ``` --- ### 完整应用场景 假设需要处理学生成绩单: ```c // 按成绩降序,成绩相同按学号升序 int compare_grade(const void *a, const void *b) { struct Student *s1 = (struct Student*)a; struct Student *s2 = (struct Student*)b; if (s1->score != s2->score) return (s2->score > s1->score) ? 1 : -1; return s1->id - s2->id; } ``` 此函数可确保成绩高的学生在前,成绩相同时学号小的优先[^3]。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值