linux sort 源码_linux内核中的排序接口--sort函数

linux内核中的sort函数,其实跟我们所说的qsort函数很像,我们来看看qsort:

qsort 的函数原型是

void qsort(void*base,size_t num,size_t width,int(__cdecl*compare)(const void*,const void*));

参数:

1 、待排序数组首地址

2 、数组中待排序元素数量

3 、各元素的占用空间大小

4 、指向函数的指针,用于确定排序的顺序。

其中compare函数应写为:

1

2

3

4

int comp(const void*a,const void*b)

{

return *(int*)a-*(int*)b;

}

其实qsort是一个典型的快速排序的接口函数。

接下来我们来看看linux内核中的排序接口函数sort:

void sort(void *base, size_t num, size_t size,

int (*cmp_func)(const void *, const void *),

void (*swap_func)(void *, void *, int size)) ;

同样的:

1、待排序的数组首地址

2、数组中待排序元素的数量

3、各元素的占用空间大小

4、指向函数的指针,用于确定排序的顺序。

5、指向函数的指针,用于交换元素的顺序(其实这可有可无,一般可以设置为NULL(空)值)。

接下来,我们来看看它的实现:

跟qsort函数的源码其实大致相似:

void sort(void *base, size_t num, size_t size,

int (*cmp_func)(const void *, const void *),

void (*swap_func)(void *, void *, int size))

{

/* pre-scale counters for performance */

int i = (num/2 - 1) * size, n = num * size, c, r;

if (!swap_func)

swap_func = (size == 4 ? u32_swap : generic_swap);

/* heapify */

for ( ; i >= 0; i -= size) {

for (r = i; r * 2 + size < n; r = c) {

c = r * 2 + size;

if (c < n - size &&

cmp_func(base + c, base + c + size) < 0)

c += size;

if (cmp_func(base + r, base + c) >= 0)

break;

swap_func(base + r, base + c, size);

}

}

/* sort */

for (i = n - size; i > 0; i -= size) {

swap_func(base, base + i, size);

for (r = 0; r * 2 + size < i; r = c) {

c = r * 2 + size;

if (c < i - size &&

cmp_func(base + c, base + c + size) < 0)

c += size;

if (cmp_func(base + r, base + c) >= 0)

break;

swap_func(base + r, base + c, size);

}

}

}

接下来我们看一个实例程序:

将代码从linux内核中抠出来,然后编写程序:

#include

#include

typedef int u32 ;

/*

fri : sort array

sec : array num

thr : array only num size

function:

function:

*/

void sort(void *base, size_t num, size_t size,

int (*cmp_func)(const void *, const void *),

void (*swap_func)(void *, void *, int size)) ;

int cmpint(const void *a, const void *b) ;

static void u32_swap(void *a, void *b, int size) ;

static void generic_swap(void *a, void *b, int size);

int main(void)

{

int array[10] = {0};

int i = 0 ;

printf("随机产生10个100以内的数:\n");

for(i = 0 ; i < 10 ; i++)

{

array[i] = rand()%100;

printf("array[%d]=%d\n",i , array[i]);

}

sort(array , 10 , sizeof(int) , cmpint , u32_swap) ;

putchar('\n');

printf("排序后的数:\n");

for(i = 0 ; i < 10 ; i++)

{

printf("arr[%d]=%d\n",i , array[i]);

}

return 0 ;

}

void sort(void *base, size_t num, size_t size,

int (*cmp_func)(const void *, const void *),

void (*swap_func)(void *, void *, int size))

{

/* pre-scale counters for performance */

int i = (num/2 - 1) * size, n = num * size, c, r;

if (!swap_func)

swap_func = (size == 4 ? u32_swap : generic_swap);

/* heapify */

for ( ; i >= 0; i -= size) {

for (r = i; r * 2 + size < n; r = c) {

c = r * 2 + size;

if (c < n - size &&

cmp_func(base + c, base + c + size) < 0)

c += size;

if (cmp_func(base + r, base + c) >= 0)

break;

swap_func(base + r, base + c, size);

}

}

/* sort */

for (i = n - size; i > 0; i -= size) {

swap_func(base, base + i, size);

for (r = 0; r * 2 + size < i; r = c) {

c = r * 2 + size;

if (c < i - size &&

cmp_func(base + c, base + c + size) < 0)

c += size;

if (cmp_func(base + r, base + c) >= 0)

break;

swap_func(base + r, base + c, size);

}

}

}

int cmpint(const void *a, const void *b)

{

return *(int *)a - *(int *)b;

}

static void u32_swap(void *a, void *b, int size)

{

u32 t = *(u32 *)a;

*(u32 *)a = *(u32 *)b;

*(u32 *)b = t;

}

static void generic_swap(void *a, void *b, int size)

{

char t;

do {

t = *(char *)a;

*(char *)a++ = *(char *)b;

*(char *)b++ = t;

} while (--size > 0);

}

运行结果:

随机产生10个100以内的数,通过排序接口sort排序后得到如下结果,验证成功!

&lpar;笔记&rpar;Linux内核中内存相关的操作函数

linux内核中内存相关的操作函数 1.kmalloc()/kfree() static __always_inline void *kmalloc(size_t size, gfp_t flags) ...

【转】linux内核中writesb&lpar;&rpar;&comma; writesw&lpar;&rpar;&comma; writesl&lpar;&rpar; 宏函数

writesb(), writesw(), writesl() 宏函数 功能 : writesb()    I/O 上写入 8 位数据流数据 (1字节) writesw()   I/O  上写入 16 ...

linux内核中的wait&lowbar;event&lowbar;interruptible&lowbar;timeout接口解析

1. 原型 #define wait_event_interruptible_timeout(wq_head, condition, timeout) \ ({ \ long __ret = time ...

Linux内核中常见内存分配函数(三)

ioremap void * ioremap (unsigned long offset, unsigned long size) ioremap是一种更直接的内存“分配”方式,使用时直接指定物理起始 ...

Linux内核中常见内存分配函数【转】

转自:http://blog.csdn.net/wzhwho/article/details/4996510 1.      原理说明 Linux内核中采用了一种同时适用于32位和64位系统的内存分页 ...

Linux内核中常见内存分配函数

1.      原理说明 Linux内核中采用了一种同时适用于32位和64位系统的内存分页模型,对于32位系统来说,两级页表足够用了,而在x86_64系统中,用到了四级页表,如图2-1所示.四级页表分 ...

Linux内核中的cmpxchg函数

http://www.longene.org/forum/viewtopic.php?t=2216 前几天,为了这个函数花了好多时间,由于参考的资料有误,一直都没有看明白,直到google之后,总算搞 ...

Linux内核中常见内存分配函数(一)

linux内核中采 用了一种同时适用于32位和64位系统的内存分页模型,对于32位系统来说,两级页表足够用了,而在x86_64系 统中,用到了四级页表. * 页全局目录(Page Global Dir ...

Linux内核中常用的数据结构和算法(转)

知乎链接:https://zhuanlan.zhihu.com/p/58087261 Linux内核代码中广泛使用了数据结构和算法,其中最常用的两个是链表和红黑树. 链表 Linux内核代码大量使用了 ...

随机推荐

Sublime插件支持Sass编译和Babel解析ES6 &amp&semi; &period;sublime-build文件初探

用Sublime Text蛮久了,配置配来配去的,每次换电脑都得重头再配过,奈何人老了脑子不中用了,得好好整理一些,下次换电脑就有得参考了.. 同事说,他的WebStorm简直太方便,自身集成了很多方 ...

Scalaz(20)-Monad: Validation-Applicative版本的Either

scalaz还提供了个type class叫Validation.乍看起来跟\/没什么分别.实际上这个Validation是在\/的基础上增加了Applicative功能,就是实现了ap函数.通过Ap ...

poj 1141 动态规划进行括号匹配

思路:黑书的例题 #include #include #include #include

kafka broker 进入 conflicted ephemeral node 死循环

转载请注明原创地址 http://www.cnblogs.com/dongxiao-yang/p/5621303.html 最近发现kafka一台服务器producer客户端写入时一直报错,查看该br ...

查看ASM 使用率

有两种方法: 1.查看v$asm_diskgroup视图 SQL> select group_number,name,total_mb,free_mb from v$asm_diskgroup; ...

javaweb-1-B&sol;S初论

一.B/S结构的基本概念 1.什么是动态网页 2.为什么需要动态网页 3.如何实现动态网页 4.为什么学习B/S技术 4.1C/S结构 优点: 1.C/S架构的界面和操作可以很丰富. 2.安全性能可以 ...

Asp&period;net Core 入门实战

Asp.Net Core 是开源,跨平台,模块化,快速而简单的Web框架. Asp.net Core官网的一个合集,方便一次性Clone 目录 快速入门 安装 一个最小的应用 项目模板 路由 静态文件 ...

给定一个实数数组,按序排列(从小到大)&comma;从数组从找出若干个数,使得这若干个数的和与M最为接近,描述一个算法,并给出算法的复杂度。

有N个正实数(注意是实数,大小升序排列) x1 , x2 ... xN,另有一个实数M. 需要选出若干个x,使这几个x的和与 M 最接近. 请描述实现算法,并指出算法复杂度. #define M 8 ...

PS 图像特效算法— —渐变

这个特效利用图层的混合原理,先设置一个遮罩层,然后用遮罩层与原图进行相乘,遮罩层不同,图像最后呈现的渐变效果也不一样. clc;clear all;close all;addpath('E:\Phot ...

在未排序的数组中找到第 k 个最大的元素

在未排序的数组中找到第 k 个最大的元素.请注意,你需要找的是数组排序后的第 k 个最大的元素,而不是第 k 个不同的元素. 示例 1: 输入: [3,2,1,5,6,4] 和 k = 2 输出: 5 ...

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值