1、PreOrder(TreeNode *t)/protected先序遍历输出树中所有的值 if(t) coutdata; PreOrder(t-LeftChild);RightChild); /if /PreOrder void Tree:PreOrder(bool enter)/public先序遍历 PreOrder(Root); if(enter)coutendl;调用代码:#define ElemType intint main() ElemType data9=1,2,NULL,3,NULL,NULL,4,NULL,NULL; Tree T1; TreeNode *t; T1.MakeN
2、ode(t,5,true,NULL); T1.InitTree(data,9); /根据data和数组长度为9建立二叉树 T1.insertLeftChild(5,t); /在编号为5的树结点的左孩子插入数字5 T1.MakeNode(t,6,true,NULL); T1.insertRightChild(5,t); /在编号为5的树结点的右孩子插入数字6 T1.MakeNode(t,9,true,NULL); T1.insertLeftChild(10,t); /在编号为10的树结点的左孩子插入数字9 T1.PreOrder(true); return 0;代码分析:代码的访问顺序:访问1,
3、输出1;访问2,输出2;访问NULL(2的左孩子);访问3,输出3;访问5,输出5;访问9,输出9;访问NULL(9的左孩子);访问NULL(9的右孩子);访问NULL(5的右孩子);访问6,输出6;访问NULL(6的左孩子),访问NULL(6的右孩子);访问4,输出4;访问NULL(4的左孩子),访问NULL(4的右孩子);输出1235964运行结果:算法2.先序遍历的非递归实现Non_Recursive_PreOrder(TreeNode*T) /protected非递归先序遍历 /* 首先进行p的输出。存储的内容基本上是右结点。 遍历左边缘不断输出,然后转到右结点入栈,继续 左边缘不断输
4、出。等到再无左边缘的时候逆向输出 所有右孩子。 */ stack s; TreeNode *p=T,*q; s.push(p);/把Root推入栈内 while(!s.empty()/如果s不空p- q=p-RightChild; if(q)s.push(q); /如果q(p的右孩子)不空则将q推入栈 p=p-LeftChild; if(!p) /如果p(p的左孩子)为空则回到(p的右孩子) p=s.top(); s.pop(); /if /while /Non_recursive_PreOrder Status Tree:Non_Recursive_PreOrder(bool enter)/
5、非递归先序遍历 Non_Recursive_PreOrder(Root); return OK; /根据data和数组长度为9建立二叉树 /在编号为10的树结点的左孩子插入数字9 T1.Non_Recursive_PreOrder(true);不断遍历左孩子,如果有右孩子就入栈。遍历到NULL的时候就读取栈首元素(即最近的一个右结点)。然后重复以上过程。访问1,输出1, 4入栈;访问2. 输出2, 3入栈;访问NULL,3出栈;访问3,输出3, 6入栈;访问5, 输出5;访问9; 输出9;访问NULL, 6出栈;访问NULL,4出栈;访问4, 输出4;算法3 中序遍历的递归实现InOrder(
6、bool enter)/public中序遍历 InOrder(Root); /InOrderInOrder(TreeNode *t)/protected中序遍历输出树中所有的值 InOrder(t- /在编号为5的树结点的右孩子插入数字6 T1.InOrder(true);访问1;访问3;访问5;算法4 中序遍历的非递归实现Non_Recursive_IndexOrder(bool enter)/非递归中序遍历 Non_Recursive_IndexOrder(Root); /Non_recursive_IndexOrderNon_Recursive_IndexOrder(TreeNode*T
7、) /protected非递归中序遍历 /* 首先不断遍历左边缘但不输出只入栈, 直到碰到NULL后(此时p=NULL)返回父结点输出父结点。 然后转到右结点入栈,继续遍历左边缘不输出 只入栈。一直遍历到某个度为0的右结点的右孩子的时候 结束一支分支的遍历。 另一支分支的遍历相同。这一支分支的遍历 结束后中序遍历结束。 */ TreeNode *p=T; s.push(NULL); while(1) while(p) s.push(p); /栈是回溯法的主要工具 p=p- /while 遍历左边缘直到NULLs.top()break;/如果栈到达栈底则跳出 p=s.top();/p=NULL的
8、时候返回其父结点或爷结点 s.pop();/弹出父结点/输出父结点/调用父结点的右孩子 /在编号为5的树结点的左孩子插入数字5 T1.Non_Recursive_IndexOrder(true);入栈,访问左孩子,入栈,访问左孩子。重复进行,一直到访问NULL。获得父节点(即栈首元素),并输出值,然后访问右结点,如果有,则重复以上过程。如果为NULL,则再次出栈输出值,继续访问右结点。访问1,入栈;访问2,入栈;访问NULL(2的左孩子),2出栈,输出2;访问3,入栈;访问5,入栈;访问9,入栈;访问NULL(9的左孩子),9出栈,输出9;访问NULL(9的右孩子),5出栈,输出5;访问NUL
9、L(5的右孩子),3出栈,输出3;访问6,入栈;访问NULL(6的左孩子),6出栈,输出6;访问NULL(6的右孩子),1出栈,输出1;访问4,入栈;访问NULL(4的左孩子),4出栈。输出4;访问NULL(4的右孩子),栈空,跳出循环;算法5 后序遍历的递归实现PostOrder(bool enter)/public后序遍历 PostOrder(Root); /PostOrderPostOrder(TreeNode *t)/protected后序遍历输出树中所有的值 PostOrder(t- T1.PostOrder(true);访问2;访问NULL(9的左孩子),访问NULL(9的右孩子)
10、,输出9;访问5,访问NULL(5的右孩子),输出5;访问3,访问6,访问NULL(6的左孩子),访问NULL(6的右孩子),输出6;访问1,访问4,访问NULL(4的左孩子),访问NULL(4的右孩子),输出4;算法6 后序遍历的非递归实现Non_Recursive_PostOrder(bool enter)/非递归后序遍历 Non_Recursive_PostOrder(Root); /Non_Recursive_PostOrderNon_Recursive_PostOrder(TreeNode*T) /protected非递归后序遍历 先进行左边缘遍历,入栈,并记载访问次数为1(tag=
11、0)。 直到p=NULL,然后返回父结点,父结点访问次数为2(tag=1)。 p转到父结点的右孩子。 重复以上步骤。 如果栈顶结点被第三次访问,则输出该结点,弹出。/用于存储树结点bools1;/用于存储结点暂离状态/没有此句函数直接结束 while(1)/如果s不空 s1.push(false); /while 用于存储左边缘树结点,全部暂离 if(s1.top() s1.pop(); cout /else 如果结点是暂离,让其准备,当第二次碰见它时就输出。此时访问右孩子 /Non_recursive_PostOrder T1.Non_Recursive_PostOrder(true);(第
12、一次访问结点入栈状态为false,第二次访问结点将状态改成true,第三次访问结点输出结点数据,避免出现第四次访问结点。)(为什么是这样?访问父节点的时候设置状态为false,访问左孩子回到父节点状态改成true,从右孩子回到父节点的时候输出父节点,共三次。非递归后序遍历的步骤:定义两个栈,第一个栈类型为 第二个栈类型为,以及树节点指针p,将NULL push进栈。循环,如果p不为空,则(树节点栈)p入栈,(状态栈)false入栈,表示还没进行第二次访问。然后不断遍历左孩子。如果状态栈首元素为true(此时为第三次访问树节点),获得栈首树节点然后输出数据,出栈。 否则状态栈首元素为false(
13、此时为第二次访问树节点),将状态改成false,然后访问其右孩子。如果到达栈底(NULL)就跳出无限循环。循环:访问1,1入栈,false入栈;访问2,2入栈,false入栈;访问NULL,跳出循环;由于栈首元素为false,false出栈,true入栈,然后访问2的右孩子;循环:访问3,3入栈,false入栈;访问5,5入栈,false入栈;访问9,9入栈,false入栈;访问NULL,跳出循环。由于栈首元素为false,false出栈,true入栈,然后访问9的右孩子循环:NULL(9的右孩子),跳出循环由于栈首元素为true,9出栈,true出栈,输出9,然后(TreeNode*)p赋值
14、为NULL;循环:p为NULL,跳出循环。由于栈首元素是false,false换成true,访问5的右孩子;循环:访问NULL(5的右孩子),跳出循环;由于栈首元素是true,5出栈,true出栈,输出5,p=NULL;循环:由于栈首元素是false,false换成true,访问3的右孩子;循环:访问6,6入栈,false入栈;访问NULL(6的左孩子),跳出循环;由于栈首元素是false,false换成true,访问6的右孩子;循环:访问NULL(6的右孩子),跳出循环;由于栈首元素是true,6出栈,true出栈,输出6,p=NULL;循环:NULL,跳出循环。由于栈首元素是true,3出
15、栈,true出栈,输出3,p=NULL;循环:由于栈首元素是true,2出栈,true出栈,输出2,p=NULL;十一:循环:NULL,跳出循环;false换成true;访问4十二:4入栈,false入栈;NULL(4的左孩子),跳出循环;False换成true;访问NULL;十三:4出栈,true出栈,输出4,p=NULL;十四:NULL,跳出循环;1出栈,true出栈,输出1,p=NULL;到达栈底,退出遍历。算法7 层次遍历LevelOrder(TreeNode *t)/protected层次遍历 /* 读取每一层的时候把下一层存进队列中。 */ TreeNode *p=t; queue p=q.front(); q.pop(); /doq.empty(); /LevelOrderLevelOrder(bool enter)/public层次遍历 LevelOrder(Root); /根据data和数组长度为9建立二叉树 T1.insertLeftChild(10,t) /在编号为10的树结点的左孩子插入数字9 T1.LevelOrder(true);完整代码:#includestringstackqu
copyright@ 2008-2022 冰豆网网站版权所有
经营许可证编号:鄂ICP备2022015515号-1