令 cur 为当前结点:
当前结点无左子树,cur 向右移动;
当前结点有左子树,找到当前结点左子树最右的结点 mostRight
i) 若mostRight->right = NULL ,令mostRight->right = cur,cur向左移动
ii) 若mostRight->right = cur,令若mostRight->right = NULL,cur向右移动
1 | //递归版本的遍历本质 |
递归的遍历即是3次来到当前节点的过程
morris 遍历
对于二叉树上的一个结点,如果它有左子树就会来到当前结点2次。如果当前结点没有左子树,则回来到该结点一次。利用左子树上最右结点的指向(NULL/CUR)来标记是第一次或是第二次达到该结点。由于每个节点都到达2次,时间复杂度为 O(n),只用了额外的2个变量,空间复杂度为 O(1)。
遍历实现:
1 | void MorrisTraversal(node *head){ |
Morris实现先序、中序和后序遍历:
1 | void MorrisPre(node *head){ |
1 | void MorrisIn(node *head){ |
后序相对复杂一些:核心思想即第二次达到自己时打印左子树上的右边界
1 | void MorrisPost(node *head){ |