c语言系统的通用数据结构,(转载)C语言实现通用数据结构的高效设计
(转载)C语言实现通用数据结构的高效设计
[复制链接]
使用宏替代模板的方案
最近在阅读一个开源的C++代码,里面用到了大量的STL里面的东西。也许是自己一直用C而很少用C++来实现算法的原因,STL里面大量的模板令人心烦。一直对STL的效率表示怀疑,但在网上搜到这样一个帖子,说C的标准库里面快速排序比STL的标准排序要慢!于是,便认真的看了下二者的源码,发现C++里面的std::sort综合运用了部分快速排序和堆排序算法,而C标准库里面用的是通用数据结构的快速排序,C标准库里面的qsort之所以比std::sort慢,是因为C语言中为了适配所有的数据结构使用了空指针。下面以更为简单的插入排序为例说明这个问题。
插入排序的算法实现代码:
void insert_sort(int a[], int n)
{
int i, j;
int t;
for (i = 1; i < n; i++) {
t = a;
j = i;
while ((j > 0) && (a[j - 1] > t)) {
a[j] = a[j - 1];
j--;
}
a[j] = t;
}
}
上述插入排序的实现只能针对整数类型进行排序,如果数据类型是浮点型,则要自己重新把代码拷贝一份,并且更改函数名以及数据类型。如果是双精度的,又或者是对自定义的结构体数组进行排序呢? 显然,这不是一种很好的解决方案。 而用空指针可以解决这个问题。
通用数据类型的插入排序实现代码:
void general_insert_sort(void* arr, int num_element, int element_bytes, int (*cmp_fun)(void* p1, void* p2))
{
int i, j;
int t[1024];
if (element_bytes > 4096){
return;
}
#define ELE(arr, i) (void*)(((unsigned)arr) + (i) * element_bytes)
for (i = 1; i < num_element; i++) {
memcpy(t, ELE(arr, i), element_bytes);
j = i;
while ((j > 0) && (cmp_fun(ELE(arr, j - 1), (void*)t))) {
memcpy(ELE(arr, j), ELE(arr, j - 1), element_bytes);
j--;
}
memcpy(ELE(arr, j), (void*)t, element_bytes);
}
}
上述通用插入排序的实现有一个限制,就是待排序数组里面每一个元素的大小不能超过4k,当然对于简单的系统预定义好的数据类型,数组元素的大小最大为double,只有8个字节,这是远远的足够用的。如果你自定义的结构体的大小太大,例如大于这里设置的4K,则没有必要用此方法排序,因为此时数据移动会占用大部分时间,此时应该考虑用索引排序的方法。
上面的方法虽然解决了任意数据类型的问题,但是其效率并不怎么高。相对于上述第一段代码而言,简单的赋值语句必须得调用一个函数来拷贝数据,简单的比较语句,则需要调用外部传入一个函数指针得到比较结果。这是效率低下的根本原因。
而C++模板参数的出现,只需要写一份代码,编译器根据你调用时候的数据类型自动生成新的代码。其实用宏也可以完成通用的功能。这里给出C语言宏的代码,C++模板的代码也很简单。
#define FIV_IMPLEMENT_INSETT_SORT(function_name, T, LT_CMP)\
void function_name(T* arr, int low, int high)\
{\
int i, j;\
T t;\
for (i = low + 1; i < high; i++) {\
t = arr;\
j = i;\
while ((j > low) && (LT_CMP(t, arr[j - 1]))) {\
arr[j] = arr[j - 1];\
j--;\
}\
arr[j] = t;\
}\
}
上面的宏定义可以看做是一种模板定义,可以用于任意数据类型。如果你要对整数进行排序,很简单,用下面的两个宏,一个宏定义比较运算,一个宏为函数定义:
#define CMP(a, b) ((a) < (b))
FIV_IMPLEMENT_INSETT_SORT(insert_sort_int, int, CMP)
这样就有一个用于整数排序的函数insert_sort_int可用,如果是你自定义的结构体类型,则同样只需要写这两个宏就可以了。
结尾:
用C++模板产生的代码大小是不使用模板的很多倍,而用C语言的空指针可以支持任意数据类型,代码大小很小,而用C语言的宏定义产生模板函数的代码大小理论上和使用STL的大小是一样的。经过本人测试,随便一个特定数据结构的快速排序递归实现,都比c++ stl里面的std::sort要快。
c语言系统的通用数据结构,(转载)C语言实现通用数据结构的高效设计相关推荐
- c 语言系统下载地址,最新晨晖C语言学习系统下载地址电脑版-CC软件
晨晖C语言学习系统是一款专业的c语言学习软件,它的页面简洁,功能强大,非常适合入门级初学者从基础开始学习c语言,它里面拥有大量的知识点以及基础知识,能够帮助初学者循序渐进打下基础,有需要的朋友快来下载 ...
- c语言系统通常将一个判断为真,C语言程序设计学习-习题2
习题二 一.选择题 1.下列4组选项中,均不是C语言关键字的选项是( A ) A.Define IF type B.getc char printf C.include scanf case D.wh ...
- r语言如何读取matlab数据类型,[转载]R语言数据类型解析[转]
寻求帮助,使用 help(solve),?solve 和 help("solve")是一样的,如果需要搜索可以用 help.search(solve) 或者 ??solve.另外使 ...
- C语言scanf函数详细解释,[转载]C语言printf和scanf函数详细用法
Printf和Scan函数的使用方法 一 printf()函数是格式化输出函数, 一般用于向标准输出设备按规定格式输出 信息.在编写程序时经常会用到此函数.printf()函数的调用格式为: prin ...
- 停车场自动计费系统 c语言,数据结构用c语言实现停车场管理完整系统.doc
数据结构用c语言实现停车场管理完整系统 题目:用C语言实现停车场管理程序的设计 天津农学院 11计算机系计科 小组成员: 王亚洲 1108014219 王浩轩 1108014208 穆建良110801 ...
- 公交线路图查询系统c语言,公交路线查询系统(基于数据结构和C语言)完整
公交路线查询系统(基于数据结构和C语言)完整 #include #include #include #include #define max 30 #define len 20 #define MAX ...
- 大学c语言基础 Turbo C2.0 (32位/64位通用)
大学c语言基础 Turbo C2.0 (32位/64位通用) 2.0此软件自带dos虚拟环境 介绍 Turbo C2.0不仅是一个快捷.高效的编译程序,同时还有一个易学.易用的集成开发环境.使用Tur ...
- (转载)Go语言最全学习路线(2022)---一站式Go学习引导!!!
原文地址:Go 学习路线(2022) 开源地址:https://github.com/yongxinz/gopher 文章目录 1.入门教程 1)Go语言中文网 - Go入门教程 2)菜鸟教程 - G ...
- MetaMap程序是如何把生物医学文本有效地匹配到一体化医学语言系统的超级词表的(转)
MetaMap程序是如何把生物医学文本有效地匹配到一体化医学语言系统的超级词表的 已有 4079 次阅读 2008-10-12 08:35|个人分类:生物医学文本挖掘|关键词:文本挖掘:自然语言处理: ...
最新文章
- oracle启用归档日志
- php-calendar,PHPCalendar的函数简介
- SmartUpload上传下载及文件名和文件内容中文问题
- 线段树专题-等差子序列 BZOJ-2124
- 2017/4/12 afternoon
- 嵌入式操作系统内核原理和开发(开篇)
- Error running ‘Unnamed‘: Unable to open debugger port (127.0.0.1:xxxx)
- 【Python】Tanimoto相似度算法实现
- React Router 全部
- 入侵他人电脑四个步骤_增长的七个步骤利用数据入侵您的业务
- Windows11以管理员身份运行命令窗口
- win10无法修改mac地址_电脑MAC地址(物理地址)修改方法
- postman接口导入
- 网络直播延迟该如何解决这个问题
- 串口总线舵机之舵机运行
- 基于java中国跳棋游戏
- 2022年,互联网上赚钱真的有那么难吗?
- linux eclipse某些项目,某些项目无法导入,因为它们已存在于Eclipse中的工作空间错误中...
- html5 cms结构,cms产品架构图.html
- eclipse中怎么快速切换窗口?
热门文章
- IDEA无法导入HttpServlet包解决方法
- 每天一个小程序—0004题(统计单词出现次数)
- SVN遇到Can't convert string from 'UTF-8' to native encoding(转)
- 【设计模式】工厂模式 Factory Pattern
- CXF(2.7.10) - A simple JAX-WS service
- 解决:Google代码achartengine曲线代码报错问题(转)
- Asp.net MVC 示例项目Suteki.Shop分析之---Model和Service
- SQL Server XML数据解析(1)
- MySQL 服务挂了 CPU 消耗接近 100% 你知道怎么回事吗???
- 精通Android自定义View(四)自定义属性使用详解