目录
13.将二叉搜索树转换成一个排序的双向链表。要求不能创建任何新的结点,只能调整树中结点指针的指向。
1.前中后序遍历(递归与非递归)
1.前序遍历
1.递归
void preOrder1(BinTree *root)
{
if (root != NULL)
{
cout << root->data << " ";
preOrder1(root->lchild);
preOrder1(root->rchild);
}
}
2.非递归
对于任一结点P:
1)访问结点P,并将结点P入栈;
2)判断结点P的左孩子是否为空,若为空,则取栈顶结点并进行出栈操作,并将栈顶结点的右孩子置为当前的结点P,循环至1);若不为空,则将P的左孩子置为当前的结点P;
3)直到P为NULL并且栈为空,则遍历结束。
void preOrder2(BinTree *root)
{
stack<BinTree*> s;
BinTree *p = root;
while (p != NULL || !s.empty())
{
while (p != NULL)
{
cout << p->data << " ";
s.push(p);
p = p->lchild;
}
if (!s.empty())
{
p = s.top();
s.pop();
p = p->rchild;
}
}
}
2.中序遍历
1.递归
void inOrder1(BinTree *root)
{
if (root != NULL)
{
inOrder1(root->lchild);
cout << root->data << " ";
inOrder1(root->rchild);
}
}
2.非递归
对于任一结点P,
1)若其左孩子不为空,则将P入栈并将P的左孩子置为当前的P,然后对当前结点P再进行相同的处理;
2)若其左孩子为空,则取栈顶元素并进行出栈操作,访问该栈顶结点,然后将当前的P置为栈顶结点的右孩子;
3)直到P为NULL并且栈为空则遍历结束。
void inOrder2(BinTree *root)
{
stack<BinTree*> s;
BinTree *p = root;
while (p != NULL || !s.empty())
{
while (p != NULL)
{
s.push(p);
p = p->lchild;
}
if (!s.empty())
{
p = s.top();
cout << p->data << " ";
s.pop();
p = p->rchild;
}
}
}
3.后序遍历
1.递归
void postOrder1(BinTree *root)
{
if (root != NULL)
{
postOrder1(root->lchild);
postOrder1(root->rchild);
cout << root->data << " ";
}
}
2.非递归
要保证根结点在左孩子和右孩子访问之后才能访问,因此对于任一结点P,先将其入栈。如果P不存在左孩子和右孩子,则可以直接访问它;或者P存 在左孩子或者右孩子,但是其左孩子和右孩子都已被访问过了,则同样可以直接访问该结点。若非上述两种情况,则将P的右孩子和左孩子依次入栈,这样就保证了 每次取栈顶元素的时候,左孩子在右孩子前面被访问,左孩子和右孩子都在根结点前面被访问。
void postOrder3(BinTree *root)
{
stack<BinTree*> s;
BinTree *cur; //当前结点
BinTree *pre = NULL; //前一次访问的结点
s.push(root);
while (!s.empty())
{
cur = s.top();
if ((cur->lchild == NULL&&cur->rchild == NULL) ||
(pre != NULL && (pre == cur->lchild || pre == cur->rchild)))
{
cout << cur->data << " "; //如果当前结点没有孩子结点或者孩子节点都已被访问过
s.pop();
pre = cur;
}
else
{
if (cur->rchild != NULL)
s.push(cur->rchild);
if (cur->lchild != NULL)
s.push(cur->lchild);
}
}
}
2.层序遍历
void printTree(BinTree *root)//层序遍历
{
queue<BinTree *> s;
s.push(root);
while (!s.empty())
{
BinTree *p = s.front();
cout << p->data << "";
s.pop();
if (p->lchild != NULL)
s.push(p->lchild);
if (p->rchild != NULL)
s.push(p->rchild);
}
}
3.求二叉树高度(深度)
int Depth(BinTree* root)
{
if (root == NULL)
return 0;
int left = Depth(root->lchild);
int right = Depth(root->rchild);
return left > right ? left + 1 : right + 1;