构造二叉树编程小结

  我想谈谈我写通过先序遍历与中序遍历来构造二叉树的一些心得体会。

  当我刚看到这个题目的时候,我觉得挺简单的,因为思路也很清晰,模块、接口很容就想出来了,但我在实际解决问题的过程中却遇到了不少障碍阻扰。

  障碍一:字符串输入的障碍。这其实不是太大的困难,主要是对于相应的STL不太熟悉。查了一下STL手册,不久就写出来了。

  障碍二:对于引用与内存分配的理解不够深入。这是一个较大的困难,纠结了我很长时间。遇到的问题是,在子函数中创建的新的树节点,在另一个子函数中都无法访问。之前怀疑是子函数结束后其分配的空间被回收(对于内存分配机制不了解),后来发现,问题不在此,而是我没有用引用,因此在子函数中改变指针指向的行为返回后被撤销。

  我的经验有三点:

  第一,子函数与相关的内存分配机制 。C中没有传引用,而C++中有。非传引用的形式传递的是形参的值,子函数接受其作为实参后在栈上开一个空间来存储它,子函数结束后将摧毁相应的栈;就算传递指针也是一样的,这一点值得注意。虽然传递指针能够修改指针指向位置的值,而且这个值可以保留到主函数中,这是因为这个值的栈是主函数开的,只有主函数结束后才摧毁,其值的改变是长久的,但是,指针本身的指向是无法改变的,改变也只是停留在子函数中。无论在哪里,用new或malloc来分配一个内存空间,都是从内存的堆区来分配一块内存,这个内存除非程序结束,否则不会自动收回。因此,当我直接传指针给子函数,又在子函数中用ptr=new btnode,当返回主函数时,new 的那部分btnode仍然存在,只不过这个时候ptr不指向它,于是这个空间就丢失了。

  第二,写代码中很耗时的一块是,缺乏思想构架时开始写,或者修改思想构架时没有修改其涉及的所有代码,或者写代码却不知道是要表达一个什么意思。我认为,这三个问题是相似的,解决这三个问题是提高编码效率的一大关键。我认为,写代码就像写文章,必须有一个思想构架(最好能够先在脑袋或纸张上写出思想伪码),然后,仔细地按照这一构架开始写,每一个小块的含义都必须清楚(最好写某一小块之前做好注释),如果中途发生了构架的改变,必须审查所有可能影响到的地方。

  第三,我想说的是,从算法到实际的代码仍然有一段距离,并不是那么简单的转换,除非你的语言掌握做的很好,因此,别眼高手低。还是要多写代码,能够做到熟练地把算法思想用代码写出来 。这很重要。

 

 

附,程序源代码:

#include #include #include #define MAX 100 using namespace std; struct btnode { btnode *lptr,*rptr;string word;}; void Creat2chaTree(string *Zlist,string *Xlist,int zi0,int xi0,int len,btnode* &ptr); int findposition(string *Zlist,string *Xlist,int zi0,int xi0,int len); void postorder(btnode* root); int main() { string st,Zlist[MAX],Xlist[MAX]; int i,j; btnode *btree; cout<<"输入先序遍历(用空格隔开,请勿在结尾增加任何空格):"; getline(cin,st); for (i=j=0;st[i]!=0;i++){ if (st[i]==' ') j++; else Xlist[j].append(&st[i],1); } cout<<"输入中序遍历(用空格隔开,请勿在结尾增加任何空格):"; getline(cin,st); for (i=j=0;st[i]!=0;i++){ if (st[i]==' ') j++; else Zlist[j].append(&st[i],1); } Creat2chaTree(Zlist,Xlist,0,0,j+1,btree); //先序遍历输出 cout<<"以下是先序遍历输出:/n"; postorder(btree); return 0; } void Creat2chaTree(string *Zlist,string *Xlist,int zi0,int xi0,int len0,btnode* &ptr) { if (len0==0) ptr=NULL; else { //creat a node ptr=new btnode; ptr->word=Xlist[xi0]; //get lenth of new string int len=findposition(Zlist,Xlist,zi0,xi0,len0); if (len<0) {cout<<"shit";exit(-1);} //recursion,left tree and right tree if (len>=0) Creat2chaTree(Zlist,Xlist,zi0,xi0+1,len,ptr->lptr); if (len<=zi0+len0) Creat2chaTree(Zlist,Xlist,zi0+len+1,xi0+len+1,len0-len-1,ptr->rptr); } } int findposition(string *Zlist,string *Xlist,int zi0,int xi0,int len) { string pat=Xlist[xi0]; for (int i=zi0,j=zi0+len;iword; postorder(root->lptr); postorder(root->rptr); } }

你可能感兴趣的:(算法与数据结构)