即在转换后的二元查找树中,左子树的结点都大于右子树的结点。
用递归和循环两种方法完成树的镜像转换。
例如输入:
8
/ /
6 10
/ / / /
5 7 9 11
输出:
8
/ /
10 6
/ / / /
11 9 7 5
定义二元查找树的结点为:
struct BSTreeNode // a node in the binary search tree (BST)
{
int m_nValue; // value of node
BSTreeNode *m_pLeft; // left child of node
BSTreeNode *m_pRight; // right child of node
};
//就是递归翻转树,有子树则递归翻转子树。
//July、2010/10/19
void Revertsetree(list *root)
{
if(!root)
return;
list *p;
p=root->leftch;
root->leftch=root->rightch;
root->rightch=p;
if(root->leftch)
Revertsetree(root->leftch);
if(root->rightch)
Revertsetree(root->rightch);
}
由于递归的本质是编译器生成了一个函数调用的栈,
因此用循环来完成同样任务时最简单的办法就是用一个辅助栈来模拟递归。
首先我们把树的头结点放入栈中。
在循环中,只要栈不为空,弹出栈的栈顶结点,交换它的左右子树。
如果它有左子树,把它的左子树压入栈中;
如果它有右子树,把它的右子树压入栈中。
这样在下次循环中就能交换它儿子结点的左右子树了。
//再用辅助栈模拟递归,改成循环的(有误之处,望不吝指正):
void Revertsetree(list *phead)
{
if(!phead)
return;
stack<list*> stacklist;
stacklist.push(phead); //首先把树的头结点放入栈中。
while(stacklist.size())
//在循环中,只要栈不为空,弹出栈的栈顶结点,交换它的左右子树
{
list* pnode=stacklist.top();
stacklist.pop();
list *ptemp;
ptemp=pnode->leftch;
pnode->leftch=pnode->rightch;
pnode->rightch=ptemp;
if(pnode->leftch)
stacklist.push(pnode->leftch); //若有左子树,把它的左子树压入栈中
if(pnode->rightch)
stacklist.push(pnode->rightch); //若有右子树,把它的右子树压入栈中
}
}
void SwapBiTree(BiTree& T)
{
if(T)
{
SwapBiTree(T->lchild);
SwapBiTree(T->rchild);
BiTree temp=T->lchild;
T->lchild=T->rchild;
T->rchild=temp;
}
}
void CreateTree(BiTree &T)
{
int i;
scanf("%d",&i);
if(i)
{
T=(BiTree)malloc(sizeof(BiTNode));
T->lchild=NULL;
T->rchild=NULL;
T->m_value=i;
CreateTree(T->lchild);
CreateTree(T->rchild);
}
else
T=NULL;
}
void Trav(BiTree T)
{
if(T)
{
Trav(T->lchild);
cout<<T->m_value<<" ";
Trav(T->rchild);
}
}
int main()
{
BiTree t=NULL;
CreateTree(t);
Trav(t);
cout<<endl;
SwapBiTree(t);
Trav(t);
return 0;
}