模板之小试牛刀---我有点明白为什么这么多人骂c++了(爱恨也交加的c++,让我不得不继续说下去)

昨天晚上有点兴奋,睡不着,哪知道又来惦记起了本主题,突然又想多说几句。

 

原来的代码中有这个遍历自然数,执行单元测试的类:

 

template< size_t N >

struct test_nature:public test_nature< N-1 >

{

test_nature():test_nature< N-1 >(){test(N);}

};

template<>

struct test_nature< 1 >

{

test_nature(){test(1);}

};

就模板的嵌套深度而言,深度达到N.多一点编译器就会报错了,现在我们就来优化它。

 

 

(哥现在并没有写代码,正边写边想哦)

 

首先的思路是在构造函数中多执行一次测试用例,深度立即减少到N/2.

 

template< size_t N >

struct test_nature:public test_nature< N-2 >

{

test_nature():test_nature< N-2 >(){test(N);test(N-1);}

};

再对N=2,N=1进行特化就可以了。复杂度可谓线性下降。

 

 

不过继承关系图是一个树形结构图,我们还可以把复杂度设法转化为对数复杂度。

思路:继承关系图中的树我们需要进行遍历整棵树,我们设法构造一棵树。复杂度立即下降到log2N。

算法一:设根节点为N,执行先序构造和后序遍历(先构造出继承关系,再让构造函数去遍历。注意这里的“构造”和“遍历”2词的含义)。然后如何构造子树呢?这是一个问题,规定策略如下:左节点是根节点左节点和当前最大的已构造节点的平均数,右节点是N-1(如果N-1已经在左树中有了,就不构造右节点)。

用几个图来说明。字体有点怪哈,不好意思。

这个构造法用模板实现有一定难度。用树结构来遍历则意味着需要用多继承,注意在生成右子树时要告诉她当前新的最大的已构造节点。

 

上面这个是个不支持vc6的版本,编译速度大幅度提高,codepad.org在线编译器可以支持300的输出,大约超过300后不再报嵌套过深而是编译时间超时错误。

 

首先定一个空节点标记static const size_t stop_tag = size_t (-1);

 

支持vc6的版本:

 

 

因为有不定多个空节点,我们不得不使用虚继承来重复继承空节点。其实不用继承,用组合是完全可以的.从数据结构讲到设计模式了,呵呵.

 

 

有机会我再来生成一棵满树,一棵avl树,一棵红黑树,呵呵.今天说到这里了.

 

哦对了,今天生成的树就是avl树,我最喜欢的一种树。我甚至在毫无意识的情况下就构造出了它,直到我输出结果我才看见我其实构造的是avl树,留给大家优化的空间已经不多了。改日还是做红黑树吧。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值