莫里斯遍历
算法原理
中序遍历
struct TreeNode{
int val;
TreeNode* left;
TreeNode* right;
TreeNode(int x) : val(x), left(NULL), right(NULL) {}
}
void inOrderMorrisTraversal(TreeNode* root){
TreeNode* pre = NULL;
TreeNode* curr = root;
while(curr != NULL){
if(curr->left == NULL){//左孩子为空,按照中序遍历规则,直接输出
cout << curr->val << endl;
curr = curr->right;//继续遍历
}
else{//左孩子不为空,找到当前结点的前驱
pre = curr->left;
while(pre->right != NULL && pre->right != curr)
pre = pre->right;//按照中序遍历规则,左子树不空的情况下,当前结点的前驱应该出现在左子树的最右侧
//退出上面while循环的条件是:(1)pre->right为空,pre->right没指向过curr,那么将pre->right指向curr
//(2)pre->right=curr,说明之前将pre->right指向过curr,这次又找到了pre说明应该将curr输出了
if(pre->right == NULL){
pre->right = curr;
curr = curr->left;
}
if(pre->right == curr){
pre->right = NULL;//恢复树的形状
cout << curr->val << endl;
curr = curr->right;
}
}
}
}
前序遍历
前序遍历与中序遍历不同的地方就在结点值输出的位置。
void preOrderTraversal(TreeNode* root){
TreeNode* pre = NULL;
TreeNode* curr = root;
while(curr != NULL){
if(curr->left == NULL){//左孩子为空
cout << curr->val << endl;
curr = curr->right;//继续遍历
}
else{//左孩子不为空,找到当前结点的前驱
pre = curr->left;
while(pre->right != NULL && pre->right != curr)
pre = pre->right;//按照中序遍历规则,左子树不空的情况下,当前结点的前驱应该出现在左子树的最右侧
if(pre->right == NULL){
pre->right = curr;
cout << curr->val << endl;
curr = curr->left;
}
if(pre->right == curr){
pre->right = NULL;//恢复树的形状
curr = curr->right;
}
}
}
}