非递归的中序线索化:我觉得重点考虑在最后一个结点的时候,由于栈的元素为空。所以为了避免使得最后一个结点的元素指向野指针,那么我们必须将结点的右指针指向null进行外部设置。
中序非递归遍历的代码
cpp
Node* previous = NULL;
void InOrderSack(Node* root)
{
stack<Node*> stk;
if (root == NULL)
{
return;
}
Node* tmpnode = NULL;
tmpnode = root;
while (tmpnode||!stk.empty())
{
while (tmpnode!=NULL)
{
stk.push(tmpnode);
tmpnode = tmpnode->lchild;
}/*已经到了左起点*/
if (!stk.empty())
{
tmpnode = stk.top();
stk.pop();
if (tmpnode->lchild == NULL)
{
tmpnode->lchild = previous;
tmpnode->ltag = 1;
}
cout << tmpnode->data << endl;
if (previous->rchild == NULL && previous !=NULL)
{
previous->rchild = tmpnode;
previous->rtag = 1;
}
previous = tmpnode;
tmpnode = tmpnode->rchild;
}
}
previous->rchild = NULL;//最后一个结点的后继结点设置为null
previous->rtag = 1;
}
中序递归遍历的代码
cpp
Node* previous = NULL;
void InOrder(Node* root)
{
if (root == NULL)
{
return;
}
Node* tmpnode = NULL;
tmpnode = root;
InOrder(tmpnode->lchild);
if (tmpnode->lchild == NULL)
{
tmpnode->lchild = previous;
tmpnode->ltag = 1;
}
if (previous->rchild == NULL && previous !=NULL)
{
previous->lchild = tmpnode;
previous->rtag = 1;
}
previous = root;
cout << tmpnode->data << endl;
InOrder(tmpnode->rchild);
}
个人感觉中序递归遍历更加简单一点
回顾先序遍历线索化流程
cpp
Node* previous;
void PreOrder(Node* root)
{
//先访问根结点 再访问左子树 再访问右子树
if (root == NULL)
{
return;
}
//根结点不为空
cout << root->data << endl;
Node* tmpnode = NULL;
tmpnode = root;
if (tmpnode->lchild == NULL )
/*上一层传入的pre使得本层结点的左子树指向上一层的先驱结点*/
{
tmpnode->lchild = previous;
tmpnode->ltag = 1;
}
if (previous->rchild == NULL && previous != NULL)
/*这里的previous保存的是上一个遍历的结点
因此如果在上一个结点的递归中,它的右子树为空
那么在它返回的下一个递归调用执行的结点,就可以当成它
右子树的连接结点也就是后继结点使用*/
{
previous->rchild = root;
}
previous = tmpnode;
/*遍历左子树和右子树*/
if (tmpnode->ltag == 0)
{
PreOrder(tmpnode->lchild);
}
if (tmpnode->rtag ==0)
{
PreOrder(tmpnode->rchild);
}
}