今天写了一下线索二叉树的建立和遍历,感受还能够,不算很难,把思路理清楚以后,就好下手了。数据结构
记得刚开始看数据结构的时候,感受很是头疼,如今愈来愈感受有意思了,固然,主要是在解决了一个问题以后的成就感让人很知足。
函数
/* 线索二叉树的创建,遍历代码实现 */ # include <stdio.h> # include <stdlib.h> # include <malloc.h> //这里失误了,刚开始都加了";"号,致使报错missing ')' before ';' # define LINK 0 # define THREAD 1 # define OK 1 # define ERROR 0 typedef char TElemType; typedef int Status; /* 线索树节点 */ typedef struct BiThrNode { TElemType data; struct BiThrNode * lchild, * rchild; //左右孩子的指针 Status LTag, RTag; }BITHRTREE, * PBITHRTREE; //定义一个全局变量pre,用于指定一个前驱元素 PBITHRTREE pre = NULL; /* 建立一颗二叉树 第一次定义这个函数的时候是这样写的 Status CreateTree( PBITHRTREE ); 报错:error C2668: 'CreateTree' : ambiguous call to overloaded function 缘由是使用了引用,而在函数前置中没有体现出来,须要改成: Status CreateTree( PBITHRTREE & ); */ Status CreateTree( PBITHRTREE & ); /* 使用递归的方法,中序遍历二叉树 */ Status InOrderTraveler( PBITHRTREE & ); /* 为二叉树添加线索 */ Status InOrderTreading( PBITHRTREE &, PBITHRTREE ); /* 中序遍历的方式添加线索 */ Status InThreading( PBITHRTREE ); /* 按照线索遍历二叉树 */ Status InOrderTraveler_Thread( PBITHRTREE & ); /* 建立一个二叉树,空格表明无子树。 函数的形参,使用引用的方式,操做简便。 */ Status CreateTree( PBITHRTREE &BaseTree ) { TElemType data; scanf( "%c", &data ); if( ' ' == data ) { BaseTree = NULL; } else { BaseTree = ( PBITHRTREE )malloc( sizeof( BITHRTREE ) ); BaseTree -> data = data; CreateTree( BaseTree -> lchild ); CreateTree( BaseTree -> rchild ); } return OK; } /* 使用递归的方法,中序遍历二叉树 PS:其实写这个中序遍历的函数,主要是想看看方才的二叉树生成了没 ……囧…… */ Status InOrderTraveler( PBITHRTREE &BaseTree ) { if( NULL != BaseTree ) { InOrderTraveler( BaseTree -> lchild ); printf( "%c", BaseTree -> data ); InOrderTraveler( BaseTree -> rchild ); } return OK; } /* 为一个二叉树添加线索,以中序为例 @param PBITHRTREE &ThreadTree 要生成的线索二叉树 @param PBITHRTREE &BaseTree 已经生成基础二叉树 return Status; */ Status InOrderTreading( PBITHRTREE &ThreadTree, PBITHRTREE BaseTree ) { //建立一个头结点 ThreadTree = ( PBITHRTREE )malloc( sizeof( BITHRTREE ) ); ThreadTree -> LTag = LINK; ThreadTree -> RTag = THREAD; ThreadTree -> rchild = ThreadTree; //右指针回指 if( NULL == BaseTree ) { ThreadTree -> lchild = ThreadTree; //基础树为空,这左孩子回指 } else { ThreadTree -> lchild = BaseTree; // 这里须要一个全局变量,来指示前驱元素 pre = ThreadTree; InThreading( BaseTree ); pre -> RTag = THREAD; pre -> rchild = ThreadTree; ThreadTree -> rchild = pre; } return OK; } /* 中序的方式设置线索 */ Status InThreading( PBITHRTREE Tree ) { if( NULL != Tree ) { InThreading( Tree -> lchild ); if( NULL == Tree -> lchild ) { //若是右孩子是空,那么放入前驱元素 Tree -> LTag = THREAD; Tree -> lchild = pre; } if( NULL == pre -> rchild ) { /* 若是这个前驱元素的右孩子为空,就把当前节点的指针赋予它 做为后继元素 */ pre -> RTag = THREAD; pre -> rchild = Tree; } pre = Tree; InThreading( Tree -> rchild ); } return OK; } /* 按照线索遍历二叉树 */ Status InOrderTraveler_Thread( PBITHRTREE & Tree ) { PBITHRTREE p = Tree -> lchild; while( p != Tree ) { /* 首先,一路查找每一个元素的ltag是否是等于1 若是等于1,说明这是第一个节点,将其值输出 注意!!! 怎么会这样呢?(其实我想说个我草),下行一开始写的 while( p -> LTag != LINK ) 没法找到第一个节点,致使遍历出错,之后长点心吧 */ while( p -> LTag != THREAD ) { //printf( "遍历到了%c,他的LTag是%d\n", p -> data, p -> LTag ); p = p -> lchild; } //循环退出,说明这是第一个节点,输出其值 printf( "%c", p -> data ); /* 查看他的LTag,若是也是1,说明是线索,直接输出 若是不是1,说明他有孩子,将指针下移一位, 从第一个while那里按照这里的思路再循环一次 */ while( p -> RTag == THREAD && p -> rchild != Tree ) { p = p -> rchild; printf( "%c", p -> data ); } p = p -> rchild; } return OK; } Status main( void ) { PBITHRTREE ThreadTree = NULL, BaseTree = NULL; //首先建造一颗不带线索的二叉树 printf( "请输入一颗二叉树:\n" ); CreateTree( BaseTree ); printf( "中序递归遍历二叉树:\n" ); InOrderTraveler( BaseTree ); printf( "\n" ); printf( "将刚才创造的二叉树线索化。…… Lording ……" ); InOrderTreading( ThreadTree, BaseTree ); printf( "\n" ); printf( "按照线索遍历二叉树:\n" ); InOrderTraveler_Thread( ThreadTree ); printf( "\n" ); return 0; } /* VC++6.0中输出的结果是 ======================================= 请输入一颗二叉树: ABEQ F CD 中序递归遍历二叉树: QEFBADC 将刚才创造的二叉树线索化。…… Lording …… 按照线索遍历二叉树: QEFBADC ======================================= 总结: 须要总结的地方太多了,都是一些白痴性错误,逻辑上仍是比较清晰的。 好比说: 预约义不用就加“;” 修改函数类型的时候,记得把前置函数定义哪里也修改了 还有就是须要在编写的时候,再 认真一些。 */
学PHP的小蚂蚁 博客 http://my.oschina.net/woshixiaomayi/blogspa