linux内核中的排序接口--sort函数
linux内核中的sort函数,其实跟我们所说的qsort函数很像,我们来看看qsort:
|
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 <stdio.h>
#include <stdlib.h>
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排序后得到如下结果,验证成功!
linux内核中的排序接口--sort函数的更多相关文章
- (笔记)Linux内核中内存相关的操作函数
linux内核中内存相关的操作函数 1.kmalloc()/kfree() static __always_inline void *kmalloc(size_t size, gfp_t flags) ...
- 【转】linux内核中writesb(), writesw(), writesl() 宏函数
writesb(), writesw(), writesl() 宏函数 功能 : writesb() I/O 上写入 8 位数据流数据 (1字节) writesw() I/O 上写入 16 ...
- linux内核中的wait_event_interruptible_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内核代码大量使用了 ...
随机推荐
- Android文件(File)操作
Android 使用与其他平台上基于磁盘的文件系统类似的文件系统. 本文讲述如何使用 Android 文件系统通过 File API 读取和写入文件. File 对象适合按照从开始到结束的顺序不跳过地 ...
- GDAL 2.0版本RPC校正速度测试
GDAL2.0版本的更新日志中提到了对RPC校正的优化,今天测试了一下,发现提升的速度还是蛮快的,测试的数据是一个IRS-P5的数据. 单线程测试 首先使用一个线程进行测试,使用下面的批处理进行运行, ...
- Android必知必会-使用okhttp的PUT方式上传文件
注:如果移动端排版有问题,请看 简书版 (<-点击左边),希望CSDN能更好的支持移动端. 背景 公司的文件上传接口使用PUT协议,之前一直用的都是老项目中的上传类,现在项目中使用了okhttp ...
- 【一天一道LeetCode】#242. Valid Anagram
一天一道LeetCode 本系列文章已全部上传至我的github,地址:ZeeCoder's Github 欢迎大家关注我的新浪微博,我的新浪微博 欢迎转载,转载请注明出处 (一)题目 Given t ...
- 学习笔记7-Android短信发送器
新建一个Android项目sns. 在String.xml添加文字 <resources> <stringname="app_name">Sns发送短信&l ...
- Java中的this关键字
//Java中的this //this引用---->当前对象的引用 /* * 1.this在什么地方(非静态的)访问另外一个成员(非静态,可以是属性或者方法) * 前面都省略了this * 2. ...
- Andriod的国际化-android学习之旅(五十八)
android资源国际化
- 【shell脚本】nginx每天自动切割日志脚本
nginx每天日志量比较大的时候,最好每天自动切割,存储,这样可以方面以后的查询和分析 #!/bin/sh ################### #filename: nginx_log_rotat ...
- findViewById中NullPointerException的错误
最近在弄一个对话框的登录时,发现一个总是报NullPointerException的错误,折腾了两小时,一直没有发现细小的区别..先上图,一边说明原因 首先是 Activity类中定义的findVie ...
- Cocos2D:塔防游戏制作之旅(十五)
Yes,貌似添加了好多的代码啊 ;] ,在你添加更多代码时,你可能注意到一些Xcode中的一些警告.首先你先忽略这些警告,我们先添加少量最终缺失的部分,然后再来解释上面代码做了什么! 在Enemy.m ...