我已经访问了许多网站,但找不到任何算法的莫里斯postOrder遍历。我知道我们可以将Morris算法用于preOrder,如果inOrder.It存在的话,如果有人给我指点postOrder莫里斯算法,它会有很大的帮助。
发布于 2019-06-20 09:30:33
一种更简单的方法是对称地进行与预定morris遍历相反的操作,并以相反的顺序打印节点。
TreeNode* node = root;
stack<int> s;
while(node) {
if(!node->right) {
s.push(node->val);
node = node->left;
}
else {
TreeNode* prev = node->right;
while(prev->left && prev->left != node)
prev = prev->left;
if(!prev->left) {
prev->left = node;
s.push(node->val);
node = node->right;
}
else {
node = node->left;
prev->left = NULL;
}
}
}
while(!s.empty()) {
cout << s.top() << " ";
s.pop();
}
cout << endl;发布于 2020-07-23 17:18:01
一旦你理解了它背后的概念,它看起来就很简单。
基本上,我们使用内部遍历( Binary )来打印给定二叉树的后序遍历( given ).我们所需要做的就是反转无序遍历的第二和第三部分,即以L N的方式打印它。
当在线程创建阶段,在前面创建的线程的帮助下再次访问节点时,这意味着我们已经遍历了左边的子树。因此,我们需要打印所有左子树节点。因此,我们打印当前节点的左子节点和右子节点的左子树节点。
在这一步之后,我们已经打印了所有的左节点,现在我们所需要做的就是打印右指针的反向顺序。如果我们认为它是一个简单的单链表,其中下一个指针是右子树中每个节点的正确子节点。
以相反的顺序打印列表,直到当前节点。转到您保存的顺序后继节点,并按照相同的顺序进行操作。
我希望这能让你的事情更清楚些。
PS:链表反转用于反转无序遍历的第二部分和第三部分。
发布于 2018-12-06 05:35:33
我的Java解决方案--它有很多代码注释,但是如果您需要更多的解释,请在这里给我注释。
public static void postOrder(Node root) {
// ensures all descendants of root that are right-children
// (arrived at only by "recurring to right") get inner-threaded
final Node fakeNode = new Node(0); // prefer not to give data, but construction requires it as primitive
fakeNode.left = root;
Node curOuter = fakeNode;
while(curOuter != null){ // in addition to termination condition, also prevents fakeNode printing
if(curOuter.left != null){
final Node curOuterLeft = curOuter.left;
// Find in-order predecessor of curOuter
Node curOuterInOrderPred = curOuterLeft;
while(curOuterInOrderPred.right != null && curOuterInOrderPred.right != curOuter){
curOuterInOrderPred = curOuterInOrderPred.right;
}
if(curOuterInOrderPred.right == null){
// [Outer-] Thread curOuterInOrderPred to curOuter
curOuterInOrderPred.right = curOuter;
// "Recur" on left
curOuter = curOuterLeft;
} else { // curOuterInOrderPred already [outer-] threaded to curOuter
// -> [coincidentally] therefore curOuterLeft's left subtree is done processing
// Prep for [inner] threading (which hasn't ever been done yet here)...
Node curInner = curOuterLeft;
Node curInnerNext = curInner.right;
// [Inner-] Thread curOuterLeft [immediately backwards] to curOuter [its parent]
curOuterLeft.right = curOuter;
// [Inner-] Thread the same [immediately backwards] for all curLeft descendants
// that are right-children (arrived at only by "recurring" to right)
while(curInnerNext != curOuter){
// Advance [inner] Node refs down 1 level (to the right)
final Node backThreadPrev = curInner;
curInner = curInnerNext;
curInnerNext = curInnerNext.right;
// Thread immediately backwards
curInner.right = backThreadPrev;
}
// curInner, and all of its ancestors up to curOuterLeft,
// are now indeed back-threaded to each's parent
// Print them in that order until curOuter
while(curInner != curOuter){
/*
-> VISIT
*/
System.out.print(curInner.data + " ");
// Move up one level
curInner = curInner.right;
}
// "Recur" on right
curOuter = curOuter.right;
}
} else {
// "Recur" on right
curOuter = curOuter.right;
}
}
}
class Node {
Node left;
Node right;
int data;
Node(int data) {
this.data = data;
left = null;
right = null;
}
}https://stackoverflow.com/questions/36384599
复制相似问题