- 1、原创力文档(book118)网站文档一经付费(服务费),不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。。
- 2、本站所有内容均由合作方或网友上传,本站不对文档的完整性、权威性及其观点立场正确性做任何保证或承诺!文档内容仅供研究参考,付费前请自行鉴别。如您付费,意味着您自己接受本站规则且自行承担风险,本站不退款、不进行额外附加服务;查看《如何避免下载的几个坑》。如果您已付费下载过本站文档,您可以点击 这里二次下载。
- 3、如文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“版权申诉”(推荐),也可以打举报电话:400-050-0827(电话支持时间:9:00-18:30)。
- 4、该文档为VIP文档,如果想要下载,成为VIP会员后,下载免费。
- 5、成为VIP后,下载本文档将扣除1次下载权益。下载后,不支持退款、换文档。如有疑问请联系我们。
- 6、成为VIP后,您将拥有八大权益,权益包括:VIP文档下载权益、阅读免打扰、文档格式转换、高级专利检索、专属身份标志、高级客服、多端互通、版权登记。
- 7、VIP文档为合作方或网友上传,每下载1次, 网站将根据用户上传文档的质量评分、类型等,对文档贡献者给予高额补贴、流量扶持。如果你也想贡献VIP文档。上传文档
查看更多
泛型算法思想的本质 转
泛型算法思想的本质 转
泛型算法思想的本质(转)2010-08-30 17:33众所周知,C++的STL实现了很多的算法,这些算法给程序员带来了很多的方便,一般情况下,如果你的项目没有特殊的要求,采用这些算法都比我们自己动手起来要简洁、高效。这些算法的成功,依赖的是大家耳熟能详的泛型思想。
你可能会说泛型编程我很熟了,不就写几个模板?没错,泛型编程是应用模板技术做一些数据抽象的过程。但在享受着它给你带来便利的同时,你是否想过这背后的设计需求是什么吗?你是否想过为什么要这样去实现吗?可能你觉得不必要去深究这些东西,毕竟只要会如何使用它就好了。但是如果你知道了为何要这样设计的原因后,我想对你总是会有些好处的。
让我们看看一个List数据结构的实现,这里我并不是去剖析STL中list的实现代码。而是用C去实现类似的功能,我想暂时先让你痛苦一下,坐拖拉机走山路。然后再让你坐豪华汽车跑高速。
typedefstruct_List
{
long Count;//链表中的元素总数
void*Item;//链表中的元素集合
long*Add)(struct_List*pList,void*pValue);
long*Clear)(struct_List*pList);
Bool(*Contains)(struct_List*pList,constvoid*pValue);
long*IndexOf)(struct_List*pList,constvoid*pValue);
long*Insert)(struct_List*pList,longindex,void*pValue);
long*Remove)(struct_List*pList,constvoid*pValue);
long*RemoveAt)(struct_List*pList,longindex);
long*Sort)(struct_List*pList);
long*Destroy)(struct_List*pList);
long*Equals)(constvoid*pValue1,constvoid*pValue2);
}List;
这个定义模拟了面向对象中的数据与方法整合在一起,它实现存放任何类型指针的集合以及对集合上的操作。
首先我们看一下这样的定义有没有什么问题,注意看结构中出现了一个Sort方法,看起来需要实现对整个List的数据进行排序。这里就涉及到一个问题,大家都知道排序有很多种类,比如:快速排序,冒泡排序,多关键字排序等。这些算法也各有特点,每个应用场景都不太一样。而现在把Sort功能与数据封装在一起,让程序库使用者如何选择想要的排序算法呢?针对每一种算法提供一个实现,封装进数据结构中,这样的话必须针对每一种数据类型都提供算法的实现,但是这样的话复用性不好,而且会产生很多重复代码。
为了不把问题搞的太复杂,也许你认为对算法的选择不那么重要,所以就选择任意一个能达到目的的算法,比如选择冒泡排序来实现,见下面的代码:
longList_Sort(List*pList)
{
longret=SUCCEED;
longi=0;
longj=0;
void*pTemp=NULL;
if(NULL==pList)
{
ret=GERR_POINT_IS_NULL;
returnret;
}
for(i=0;ipListCount-1;i++)
{
for(j=i+1;jpListCount;j++)
{
if(pListEquals(pListItem[i],pListItem[j])0//用了Equals方法
{
pTemp=pListItem[i];
pListItem[i]=pListItem[j];
pListItem[j]=pTemp;
}
}
}
returnret;
}
请注意有注释的那段代码,Sort方法调用了一个叫Equals方法。该方法也是由集合封装的。粗看起来没有什么问题,接着我们再看看Equals方法的实现。
longArrayList_Equals(const void*pValue1,const void*pValue2)
{
return strcmp(pValue1,pValue2);
}
啊,看起来真的好简洁,直接调用了一个库函数strcmp就完成了任务。我想学过C的程序员一看到strcmp就很亲切。不过不要高兴的太早,让我们回到数据项的定义:void*Item;这里的指针类型是void,说明它可以存放任何数据类型。而刚才Equals的实现却是用字符串的比较函数,也就是说这个list只能存放字符类型的才能保证产生正确的结果。要是遇上里面存放的是INT或其它结构体类型的数据,那不就麻烦了。难道需要针对每一种数据类型都实现一个排序版本
原创力文档


文档评论(0)