实现遍历二叉树遍历(前中后层序/非递归)
最近使用开发的过程中出现了一个小问题,顺便记录一下原因和方法--实现遍历
感激考参如下
一:前中后序递归实现
/* 前中后序的递归实现懂得起来最为单简,要点在于visit(node)的位置。 */ /* 前中后序递归实现 */ //序前历遍 void BT_PreOrder(BitTree node) { if(!node) return; visit(node); BT_PreOrder(node->left); BT_PreOrder(node->right); } //中序历遍 void BT_InOrder(BitTree node) { if(!node) return; BT_PreOrder(node->left); visit(node); BT_PreOrder(node->right); } //中序历遍 void BT_PostOrder(BitTree node) { if(!node) return; BT_PreOrder(node->left); BT_PreOrder(node->right); visit(node); }
二:层序递归实现
/* 层序历遍 这类式方用队列来实现,也是最易容懂得的式方,路思如下: 按照层序历遍的定义,问访完以后节点之后,则以后节点的左子节点具有了倒数第二优先级,以后节点的右子节点具有了倒数第一优先级,用利队列先进先出的特性(可以肯定最低的优先级),可以实现。 */ void BT_LevelOrder(BitTree node) { if(!node) return; queue<BitTree> q; q.push(node); BitTree pvNode; while(!q.empty()) { pvNode = q.pop(); visit(pvNode); if(!pvNode->left) q.push(pvNode->left); if(!pvNode->right) q.push(pvNode->right); } }
三:序前非递归实现
/* 序前历遍非递归实现1 这类式方用栈来实现,也是最易容懂得的式方,路思如下: 按照序前历遍的定义,问访完以后节点之后,则以后节点的左子节点具有了第一优先级,以后节点的右子节点具有了第二优先级, 用利栈后进先出的特性(可以肯定最高的优先级),可以实现。 */ void BT_PreOrderNoRec(BitTree node) { if(!node) return; stack<BitTree> s; BitTree pvNode; s.push(node); while(!s.empty()) { pvNode = s.pop(); visit(pvNode); if(!pvNode->right) s.push(pvNode->right); if(!pvNode->left) s.push(pvNode->left); } } /* 序前历遍非递归实现2 在网上看到的一种写法,个人认为不如第一种实现起来更易懂 */ void BT_PreOrderNoRec2(BitTree node) { if(!node) return; stack<BitTree> s; while(!node && !s.empty()) { /*如果以后节点不为空,则直接问访,然后将节点存储到栈中(仅仅用来未来找寻右子节点),然后以后节点变成左字节点*/ if(node) { visit(node); s.push(node); node = node->left; } /*如果以后节点为空,则到栈中出取上一个节点,并找出右子节点行进问访*/ else { node = s.pop(); node = s.right; } } }
四:中序非递归
/* 中序历遍非递归实现 用栈来实现,这类式方可以用递归的路思来懂得 */ void BT_InOrderNoRec(BitTree node) { if(!node) return; stack<BitTree> s; while(!s.empty()) { /*如果以后节点不为空,则不问访,而是将它放入栈中,然后以后节点变成左字节点; 直一取采这类式方,根据栈先进后出的点特,未来问访的时候左字节点在前,以后节点在后; 正好是中序历遍的特性 */ if(!node) { push(node); node = node->left(); } /*如果以后节点为空,则去栈里出取节点问访,然后问访右子节点。 这里有些好不懂得,其实这里的开始是左字节点为空了,所以问访了以后节点,然后右子节点; 同时以后节点为根的二叉树实际上是层上的左字节点,次依类推正好是中序历遍的特性 */ else { node = s.pop(); visit(node); node = node->right; } } }
五:后序非递归
/* 后序历遍非递归实现 用栈来实现,不是很好懂得,但是最少不必借助各种标记位 路思如注释所写 */ void BT_PostOrderNoRec(BitTree node) { if(!node) return; stack<BitTree> s; BitTree tmp;//用来标记刚刚问访过的节点 while(!node && !s.empty()) { //如果以后节点不为空,则压入栈,以后节点变成左字节点 if(node) { s.push(node); node = node->left; } //如果为空,则需要根据栈顶的节点来定判下一步 else { //获得栈顶节点,不是pop node = s.getPop(); //如果栈顶节点有右子节点,并且(这好不懂得,但很要重)右子节点不是我们刚刚问访过的, //则,我们要去右子树问访 if(node->right && node->right != tmp) { //把右子树看成一个新的开始行进问访:根节点压入栈,问访左字节点 s.push(node->right); node = node->right->left; } //如果栈顶节点没有右子节点,或者我们刚刚问访过右子节点,则到达后序历遍的求要,我们可以问访以后节点 else { //问访以后节点,设置标记节点(tmp)为以后节点,以后节点置为空 node = s.pop(); visit(node); tmp = node; node = null; } } } }
文章结束给大家分享下程序员的一些笑话语录:
问路
有一个驾驶热气球的人发现他迷路了。他降低了飞行的高度,并认出了地面 上的一个人。他继续下降高度并对着那个人大叫,“打扰一下,你能告诉我我 在哪吗?”
下面那个人说:“是的。你在热气球里啊,盘旋在 30 英尺的空中”。
热气球上的人说:“你一定是在 IT 部门做技术工作”。
“没错”,地面上的人说到,“你是怎么知道的?”
“呵呵”,热气球上的人说,“你告诉我的每件事在技术上都是对的,但对都没 有用”。
地面上的人说,“你一定是管理层的人”。
“没错”,热气球上的人说,“可是你是怎么知道的?”
“呵呵”,地面上的那人说到,“你不知道你在哪里,你也不知道你要去哪,你 总希望我能帮你。你现在和我们刚见面时还在原来那个地方,但现在却是我 错了”。