相信你行,你会发现你真的行!试一试!你会惊讶地发现那么多美妙的事情会降临。
——摘自 奥格.曼狄诺《羊皮卷》第15题: 题目:输入一颗二元查找树,将该树转换为它的镜像,
即在转换后的二元查找树中,左子树的结点都大于右子树的结点。
用递归和循环两种方法完成树的镜像转换。
例如输入:
8
/ \
6 10
/ \ / \
5 7 9 11
输出:
31
8
/ \
10 6
/ \ / \
11 9 7 5
/*递归的本质是编译时产生函数调用栈,利用循环加上辅助栈可以完成递归功能;*/
/*递归思想:左右子树整体交换;*/
#include <iostream>
#include <stdlib.h>
#include <stdio.h>
#include <assert.h>
#include <stack>
using namespace std;
typedef struct BTreeNode
{
int Value;
struct BTreeNode* Leftchild;
struct BTreeNode* Rightchild;
}Tnode,*Tree;
void addTree(Tree& T, int num)
{
if(T == NULL)
{
T = (BTreeNode *)malloc(sizeof(Tnode));
T->Value = num;
T->Leftchild = NULL;
T->Rightchild = NULL;
}
else if(T->Value > num)
{
addTree((T->Leftchild), num);
}
else if(T->Value < num)
{
addTree((T->Rightchild), num);
}
else
{
cout << "重复加入同一结点" << endl;
}
}
void dis_Mtree(Tree T)
{
if(T!=NULL)
{
dis_Mtree(T->Leftchild);
cout<<T->Value;
dis_Mtree(T->Rightchild);
}
}
void reverse(Tree T)/*递归*/
{
if(T!=NULL)/*参数检查*/
{
reverse(T->Leftchild);
reverse(T->Rightchild);
Tree Plist=T->Leftchild;
T->Leftchild=T->Rightchild;
T->Rightchild=Plist;
}
}
void reverse_2(Tree T)/*循环+辅助栈*/
{
assert(Tree!=NULL);
stack<Tree> stacklist;
stacklist.push(T); /*首先把树的头结点放入栈中。*/
while(stacklist.size())
{
Tree pnode=stacklist.top();
stacklist.pop();
Tree ptemp;
ptemp=pnode->Leftchild;
pnode->Leftchild=pnode->Rightchild;
pnode->Rightchild=ptemp;
if(pnode->Leftchild)
stacklist.push(pnode->Leftchild);
if(pnode->Rightchild)
stacklist.push(pnode->Rightchild);
}
}
void destroy(Tree T)
{
Tree T1;
if(T!=NULL)
{
T1=T;
destroy(T1->Leftchild);
destroy(T1->Rightchild);
cout<<"free node :"<<T->Value;
free(T1);
T1=NULL;
}
}
int main()
{
Tree T = NULL;
addTree(T, 8);
addTree(T, 6);
addTree(T, 10);
addTree(T, 5);
addTree(T, 7);
addTree(T, 9);
addTree(T, 11);
dis_Mtree(T);
cout<<endl;
reverse(T);
dis_Mtree(T);
cout<<endl;
reverse_2(T);
dis_Mtree(T);
cout<<endl;
destroy(T);
return 1;
}