这道题的题目可以描述为:完成一个函数,输入一个二叉树,该函数输出它的镜像。
本文中有关二叉树结构体和接口定义如下:
typedef int DataType;
typedef struct BSTreeNode{
DataType data;
struct BSTreeNode *left;
struct BSTreeNode *right;
} BSTreeNode;
BSTreeNode *CreateNode(int data)
{
BSTreeNode *node = (BSTreeNode *)malloc(sizeof(BSTreeNode));
node->data = data;
node->left = NULL;
node->right = NULL;
return node;
}
下面将总结出递归和非递归了两种实现方法:
1.递归算法
其思路可以理解为:先序遍历这颗树的每个结点,如果遍历到的结点有子结点,就交换它的两个子结点,当交换完所有非叶子结点,就得到了树的镜像。
代码如下:
void Mirror1(BSTreeNode *root)
{
if (root == NULL)
{
return;
}
Mirror1(root->left);
Mirror1(root->right);
BSTreeNode *t = root->left;
root->left = root->right;
root->right = t;
}
2.非递归算法:
非递归算法中采用了利用栈实现树的非递归后序遍历,有关栈的相关定义如下:
struct BSTreeNode;
typedef struct BSTreeNode * QDataType;
#define MAXSIZE (100)
typedef struct{
QDataType array[MAXSIZE];
int top;//起了个别名,含义还是size
}Stack;
void StackInit(Stack *ps)
{
ps->top = 0;
}
void StackDestory(Stack *ps)
{
ps->top = 0;
}
//栈中入放一个元素
void StackPush(Stack *ps, QDataType data)
{
assert(ps->top < MAXSIZE);
ps->array[ps->top++] = data;
}
//栈中弹出一个元素
void StackPop(Stack *ps)
{
assert(ps->top>0);
ps->top--;
}
//弹出栈顶元素
QDataType StackTop(const Stack *ps)
{
assert(ps->top > 0);
return ps->array[ps->top - 1];
}
//返回栈的大小
int StackSize(const Stack *ps)
{
return ps->top;
}
//返回栈是否为空
int StackEmpty(const Stack *ps)
{
return ps->top == 0 ? 1 : 0;
}
其思路可以理解为:从根结点开始,采用后序依次向下循环遍历这颗树的每个结点。如果根是空结点,直接返回,或者将左右子树调换即可。
代码如下:
void Mirror2(BSTreeNode *root)
{
Stack stack;
StackInit(&stack);
//last上一个被遍历过的结点
BSTreeNode *cur, *top, *last = NULL;
cur = root;
while (cur != NULL || !StackEmpty(&stack))
{
//遍历左子树
while (cur != NULL)
{
StackPush(&stack, cur);
cur = cur->left;
}
//top的左子树已经遍历过了
top = StackTop(&stack);
if (top->right == NULL || top->right == last)
{
//如果右子树被遍历过了
StackPop(&stack);
BSTreeNode *t = root->left;
root->left = root->right;
root->right = t;
//记录被遍历的结点
last = top;
}
else
{
//如果右子树没有被遍历
cur = top->right;
}
}
}