随笔 - 87  文章 - 279  trackbacks - 0
<2024年12月>
24252627282930
1234567
891011121314
15161718192021
22232425262728
2930311234

潜心看书研究!

常用链接

留言簿(19)

随笔分类(81)

文章分类(89)

相册

ACM OJ

My friends

搜索

  •  

积分与排名

  • 积分 - 214751
  • 排名 - 116

最新评论

阅读排行榜

评论排行榜

问题分析:
假设一个
struct TreeNode
{
    int tData;
    TreeNode *lp, *rp;//左右儿子的指针
};

规定用递归前序遍历以pNode为根二叉树,把节点指针保存在rs数组中,并返回节点个数cnt.

因为要用递归遍历, 所以cnt必须保留递归每层cnt的值.
实现方法有两种:
1:用by value传值,cnt初值为0;

int travel(TreeNode *pNode, TreeNode **rs, int &cnt)
{
    if (pNode == NULL)
    {
        return cnt;
    }
    rs[cnt++] = pNode;
    travel(pNode->lp, rs, cnt);
    travel(pNode->rp, rs, cnt);
    return cnt;
}

2:用静态变量实现
int travel(TreeNode *pNode, TreeNode **rs)
{
    static int cnt = 0;
    if (pNode == NULL)
    {
        return cnt;
    } 
    rs[cnt++] = pNode;
    travel(pNode->lp, rs, cnt);
    travel(pNode->rp, rs, cnt);
    return cnt;
}

对比1和2,显然2的函数要比1的来得友好,因为在1中增加的参数cnt不属于函数接口,只是为了函数的实现而引入的,所以参数cnt的出现,破坏了接口的友好性.但是如果用2的方法,在函数再次使用的时候static int cnt的值仍保持上次函数被调用时的值,而没有初始化为0,从而达不到函数再次被调用的目的.那有没有好的解决方法呢?

我们利用函数重载,重载travel函数,并在此函数内调用1的travel函数.

int travel(TreeNode *pNode, TreeNode **rs)
{
    int cnt = 0;
    return travel(TreeNode *pNode, TreeNode **rs, int &cnt);
}

这样的话,就能很好的解决了函数接口的友好性,而又不会出现static变量的副作用了.


以上是小弟的一点愚见.

posted on 2006-03-14 13:11 阅读(1187) 评论(9)  编辑 收藏 引用 所属分类: C++之梦

FeedBack:
# re: 从二叉树的递归遍历想到的:利用重载函数,使函数接口更"友好" 2006-03-14 13:24 cf
第二种static的写法的确是愚见,呵呵

这么一来用户岂不是只能travel一遍了,第二遍的第一个期望的cnt已经不是0了(node数不为0)  回复  更多评论
  
# re: 从二叉树的递归遍历想到的:利用重载函数,使函数接口更"友好" 2006-03-14 17:57 
目的是说,第一和第二种方法都不可采,我已经说明了,请仔细看随笔:)  回复  更多评论
  
# re: 从二叉树的递归遍历想到的:利用重载函数,使函数接口更"友好" 2006-03-14 18:18 小明
明白楼主的意思,但是我觉得这个cnt应该由数组对象去维护

如果用vector就是这个样子
void travel(TreeNode *pNode, vector<TreeNode*> &rs)
{
if (pNode == NULL)
{
return;
}
rs.push_back(pNode);
travel(pNode->lp, rs);
travel(pNode->rp, rs);
return ;
}  回复  更多评论
  
# re: 从二叉树的递归遍历想到的:利用重载函数,使函数接口更"友好" 2006-03-14 21:59 
嗯, 的确是的, 从数组的确可以求出数组元素个数, 但是如果只要求求出节点的个数,不保留元素,即不用数组的话,我想就还是要用我这种方法吧 :)  回复  更多评论
  
# re: 从二叉树的递归遍历想到的:利用重载函数,使函数接口更"友好" 2006-03-15 11:15 小明
当然,还可以使用默认参数
int travel(TreeNode *pNode, TreeNode **rs, int cnt = 0)
{
if (pNode == NULL)
{
return cnt;
}
rs[cnt] = pNode;
if(pnode->lp) cnt = travel(pNode->lp, rs, cnt+1);
if(pnode->rp) cnt = travel(pNode->rp, rs, cnt+1);
return cnt;
}
  回复  更多评论
  
# re: 从二叉树的递归遍历想到的:利用重载函数,使函数接口更"友好" 2006-03-15 13:02 
这个可以吗,比如到一棵 3 层 满二叉树, 函数不是返回 3 吗?  回复  更多评论
  
# re: 从二叉树的递归遍历想到的:利用重载函数,使函数接口更"友好" 2006-04-09 10:03 dzz
豪阿,我昨天去zju做了两道题目,有一道1879觉得很简单但是我的源码一直WA.
有空帮我看看,谢谢~!
#include <iostream>
#include <cmath>
using namespace std;
int q[3000]={0};
long s[3000]={0};
int length;
long c1=0,c2=0;
int flag=0;
int ctr=0;
main(){
while(cin>>length){
for(ctr=0;ctr<length;ctr++)
cin>>s[ctr];
for(ctr=0;ctr<length;ctr++){
if(ctr==0) ;
else {
if(q[abs(s[ctr]-s[ctr-1])]||(abs(s[ctr]-s[ctr-1])>=length)||(abs(s[ctr]-s[ctr-1]))<=0) {flag=-1;break;}
else {q[abs(s[ctr]-s[ctr-1])]=1;if(ctr==length-1) flag=1;}
}
}
if(flag==-1) cout<<"Not jolly"<<endl;
else cout<<"Jolly"<<endl;
memset(q,0,length*sizeof(int));
memset(s,0,length*sizeof(long));
}
}
  回复  更多评论
  
# re: 从二叉树的递归遍历想到的:利用重载函数,使函数接口更"友好" 2006-04-23 12:26 
你会不会理解错题意呢?

1 4 2 3

|4-1|=3
|2-4|=2
|3-2|=1

1 - n-1 的数都在

所以是 "Jolly";  回复  更多评论
  
# re: 从二叉树的递归遍历想到的:利用重载函数,使函数接口更"友好" 2006-04-23 12:46 
#include <iostream>
#include <cmath>
using namespace std;

int main()
{
int caseTime;
int d[3000];
int lNum, rNum;
int i;
bool is_first_flag;
bool flag;

while (cin >> caseTime)
{
for (i=1; i<=caseTime-1; i++)
{
d[i] = 0;
}
is_first_flag = true;
for (i=0; i<caseTime; i++)
{
if (is_first_flag)
{
cin >> rNum;
is_first_flag = false;
}
else
{
lNum = rNum;
cin >> rNum;
if (abs(rNum-lNum) >=1 && abs(rNum-lNum) <= caseTime-1)
{
// cout << "d=" << abs(rNum-lNum) << endl;
d[abs(rNum-lNum)] = 1;
}
}
}
flag = true;
for (i=1; i<=caseTime-1; i++)
{
if (d[i] == 0)
{
flag = false;
break;
}
}
if (flag)
{
cout << "Jolly" << endl;
}
else
{
cout << "Not jolly" << endl;
}
}
return 0;
}
我的代码  回复  更多评论
  

只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   博问   Chat2DB   管理