user-0 提问: 求大佬帮我看看这段二叉树Morris后序遍历的代码

回复:
user: user-1
content: 引用 2 楼 weixin_45906870 的回复:改成你的代码后编译没问题，但是运行时编译器会停止工作，但是我不知道问题出在哪  不好意思，因为没调试，有笔误 void postorderTraverse(struct TreeNode *root) {     if (root==NULL) return;     struct TreeNode *p = NULL;     //struct TreeNode *t1 =malloc(sizeof(struct TreeNode)); //没必要用t1     //t1->left = root;     //t1->right = NULL;     //struct TreeNode *t = t1;     struct TreeNode* t = root; //直接t从root开始就可以     while (t){         p = t->left;         //if (t->left){         //if (p->left){         if(p) { //这里笔误了             //p = t->left;             while (p->right!=NULL && p->right!=t){                 p = p->right;             }             if (p->right==NULL){                 p->right = t;                 t = t->left;             }             else{                 //printreverse(t->left, p);                 p->right = NULL; //为了节点逆转的判断，先恢复右节点为NULL                 printreverse(t->left); //再逆向打印                 t = t->right;             }         }         else{             t = t->right;         }     }     //free(t1); }

user: user-1
content: 给你一个递归和morris遍历的完整代码 其实我觉得morris的后序遍历为了省空间，需要逆向打印（遍历），时间上也多消耗的，以时间换空间，也不见得有多好  struct TreeNode {     int val;     struct TreeNode *left;     struct TreeNode *right; };   struct TreeNode* reverse(struct TreeNode *node) {     struct TreeNode* pre = NULL;     struct TreeNode* next = NULL;     while (node != NULL){         next = node->right;         node->right = pre;         pre = node;         node = next;     }     return pre; }   void printreverse(struct TreeNode *node) {     struct TreeNode* tail =reverse(node);     struct TreeNode* cur = tail;     while (cur != NULL ){         printf("%d ", cur->val);         cur =cur->right;     }     reverse(tail); }  void postorderTraverse(struct TreeNode *root) //morris后序 {     if (root==NULL) return;     struct TreeNode *p = NULL;     struct TreeNode* t = root;     while (t){         p = t->left;         if(p) {             while (p->right!=NULL && p->right!=t){                 p = p->right;             }             if (p->right==NULL){                 p->right = t;                 t = t->left;                 continue;             }             else{                 p->right = NULL;                 printreverse(t->left);             }         }         t = t->right;     }     printreverse(root); //最后打印右子树 }  void preorderTraverse(struct TreeNode *root) { //morris前序     if(root == NULL) return;     struct TreeNode* cur = root;     struct TreeNode* right = NULL;     while (cur != NULL){         right = cur->left;         if(right != NULL){             while (right->right != NULL && right->right != cur){                 right = right->right;             }             if(right->right == NULL){                 right->right = cur;                 printf("%d ", cur->val);                 cur = cur->left;                 continue;             }else {                 right->right = NULL;             }         }else {             printf("%d ", cur->val);         }         cur = cur->right;     } }  void inorderTraverse(struct TreeNode *root) { //morris中序     if(root == NULL) return;     struct TreeNode* cur = root;     struct TreeNode* right = NULL;     while (cur != NULL){         right = cur->left;         if(right != NULL){             while (right->right != NULL && right->right != cur){                 right = right->right;             }             if(right->right == NULL){                 right->right = cur;                 cur = cur->left;                 continue;             }else {                 right->right = NULL;             }         }         printf("%d ", cur->val);         cur = cur->right;     } }  void preOrder(struct TreeNode* root) {     if (root==NULL) return;     printf("%d ", root->val);     preOrder(root->left);     preOrder(root->right); }  void inOrder(struct TreeNode* root) {     if (root==NULL) return;     inOrder(root->left);     printf("%d ", root->val);     inOrder(root->right); }  void postOrder(struct TreeNode* root) {     if (root==NULL) return;     postOrder(root->left);     postOrder(root->right);     printf("%d ", root->val); }  void createTree(struct TreeNode** node, int *data, int length, int *index) {     if(data[*index]==-1) {         (*index)++;         return;     }     if(*node==NULL) *node=(struct TreeNode*)malloc(sizeof(struct TreeNode));     (*node)->left = NULL;     (*node)->right = NULL;     (*node)->val = data[(*index)++];     if (*index<length)         createTree(&((*node)->left), data, length, index);     if (*index<length)         createTree(&((*node)->right), data, length, index); }  void destroyTree(struct TreeNode* root) {     if (root==NULL) return;     destroyTree(root->left);     destroyTree(root->right);     free(root); }  int main() {     struct TreeNode *root=NULL;     int data[]={0,1,2,-1,-1,3,-1,-1,4,5,-1,-1,6};     int index=0;     createTree(&root, data, 13, &index);     printf("递归前序\n");     preOrder(root);     printf("\nmorris前序\n");     preorderTraverse(root);     printf("\n递归中序\n");     inOrder(root);     printf("\nmorris中序\n");     preorderTraverse(root);     printf("\n递归后序\n");     postOrder(root);     printf("\nmorris后序\n");     postorderTraverse(root);     printf("\n");     destroyTree(root);     return 0; }

user: user-0
content: 引用 1 楼 user-1 的回复：这是morris后序遍历必须的步骤，也就是先遍历到左子树的最右节点，才开始逆向打印。所以逆向打印步骤省不了，优化的地方有限，关键就看逆向打印怎么实现。通常的做法就是先把节点逆转，打印结束后再把节点逆转回来。 如果非要改进，参考以下代码吧  struct TreeNode {     int val;     struct TreeNode *left;     struct TreeNode *right; };  struct TreeNode* reverse(struct TreeNode *node) {     struct TreeNode* pre = NULL;     struct TreeNode* next = NULL;     while (node != NULL){         next = node->right;         node->right = pre;         pre = node;         node = next;     }     return pre; }  void printreverse(struct TreeNode *node) {     struct TreeNode* tail =reverse(node);     struct TreeNode* cur = tail;     while (cur != NULL ){         printf("%d\n", cur->val);         cur =cur->right;     }     reverse(tail); }  void postorderTraverse(struct TreeNode *root) {     if (root==NULL) return;     struct TreeNode *p = NULL;     //struct TreeNode *t1 =malloc(sizeof(struct TreeNode)); //没必要用t1     //t1->left = root;     //t1->right = NULL;     //struct TreeNode *t = t1;     struct TreeNode* t = root; //直接t从root开始就可以     while (t){         p = t->left;         //if (t->left){         if (p->left){             //p = t->left;             while (p->right!=NULL && p->right!=t){                 p = p->right;             }             if (p->right==NULL){                 p->right = t;                 t = t->left;             }             else{                 //printreverse(t->left, p);                 p->right = NULL; //为了节点逆转的判断，先恢复右节点为NULL                 printreverse(t->left); //再逆向打印                 t = t->right;             }         }         else{             t = t->right;         }     }     //free(t1); }改成你的代码后编译没问题，但是运行时编译器会停止工作，但是我不知道问题出在哪

user: user-1
content: 这是morris后序遍历必须的步骤，也就是先遍历到左子树的最右节点，才开始逆向打印。所以逆向打印步骤省不了，优化的地方有限，关键就看逆向打印怎么实现。通常的做法就是先把节点逆转，打印结束后再把节点逆转回来。 如果非要改进，参考以下代码吧  struct TreeNode {     int val;     struct TreeNode *left;     struct TreeNode *right; };  struct TreeNode* reverse(struct TreeNode *node) {     struct TreeNode* pre = NULL;     struct TreeNode* next = NULL;     while (node != NULL){         next = node->right;         node->right = pre;         pre = node;         node = next;     }     return pre; }  void printreverse(struct TreeNode *node) {     struct TreeNode* tail =reverse(node);     struct TreeNode* cur = tail;     while (cur != NULL ){         printf("%d\n", cur->val);         cur =cur->right;     }     reverse(tail); }  void postorderTraverse(struct TreeNode *root) {     if (root==NULL) return;     struct TreeNode *p = NULL;     //struct TreeNode *t1 =malloc(sizeof(struct TreeNode)); //没必要用t1     //t1->left = root;     //t1->right = NULL;     //struct TreeNode *t = t1;     struct TreeNode* t = root; //直接t从root开始就可以     while (t){         p = t->left;         //if (t->left){         if (p->left){             //p = t->left;             while (p->right!=NULL && p->right!=t){                 p = p->right;             }             if (p->right==NULL){                 p->right = t;                 t = t->left;             }             else{                 //printreverse(t->left, p);                 p->right = NULL; //为了节点逆转的判断，先恢复右节点为NULL                 printreverse(t->left); //再逆向打印                 t = t->right;             }         }         else{             t = t->right;         }     }     //free(t1); }