面试题19:二叉树的镜像(来自《剑指Offer》)
题目:请完成一个函数,输入一个二叉树,该函数输出它的镜像。
二叉树结点的定义如下:
[cpp] view plain copy print ?
1. struct
2. {
3. int
4. BinaryTreeNode *Left;
5. BinaryTreeNode *Right;
6. };
通过画图,可知二叉树的镜像如下图所示:
根据画图可得到这样的思路:先序遍历树的每个结点,若遍历到的结点有子结点,则交换它的两个子结点。
有两种实现方法:
1.递归实现
[cpp] view plain copy print ?
1. void
2. {
3. if(NULL == pNode)
4. return;
5. if(NULL == pNode->Left && NULL == pNode->Right)
6. return;
7.
8. BinaryTreeNode *pTemp = pNode->Left;
9. pNode->Left = pNode->Right;
10. pNode->Right = pTemp;
11.
12. if(pNode->Left)
13. MirroRecursively(pNode->Left);
14. if(pNode->Right)
15. MirroRecursively(pNode->Right);
16. }
2.非递归实现,即使用循环实
void MirrorNonRecurively(BinaryTreeNode *pNode)
{
if(NULL == pNode)
return;
stack<BinaryTreeNode *> stackTreeNode;
stackTreeNode.push(pNode);
while(stackTreeNode.size())
{
BinaryTreeNode *pNode = stackTreeNode.top();
stackTreeNode.pop();
if(NULL != pNode->Left || NULL != pNode->Right)
{
BinaryTreeNode *pTemp = pNode->Left;
pNode->Left = pNode->Right;
pNode->Right = pTemp;
}
if(NULL != pNode->Left)
stackTreeNode.push(pNode->Left);
if(NULL != pNode->Right)
stackTreeNode.push(pNode->Right);
}
}
链表的逆置问题:
利用链表的头插法和尾插法
1,我们不应该使得链表断裂,也就是说:无论什嘛时候,我们都必须能访问到数据
void Reverse(LinkList H)
{
LNode *p, *q;
p = H->next;
H->next = NULL;
while(p)
{
q = p;
p = p->next;
q->next = H->next;
H->next = q;
}
}
合并两个排序的链表
1,容易犯的两种错误:
1,在写代码之前没有对合并的过程想清楚,最终合并出来的链表要么中间断开了要么并没有做到
递增排序;
2,代码在鲁棒性方面存在问题,程序一旦有特殊的输入(如:空链表)就会崩溃
1,第一个链表是空链表,也就是头节点是一个空指针,那么它和第二个链表合并,显然合并
的结果就是第二个链表;同样的,当输入的第二个链表的头节点是空指针的时候,我们把
它和第一个链表合并得到的结果就是第一个链表;如果两个链表都是空的,那么合并的结
果就是一个空链表。。。。。。。
Node *ListMerge1(Node *head1,Node *head2)//采用递归的方法实现
{
if(head1==NULL)
return head2;
if(head2==NULL)
return head1;
Node *head=NULL;
if(head1->value < head2->value)
{
head=head1;
head->next=ListMerge1(head1->next,head2);
}
else
{
head=head2;
head->next=ListMerge1(head1,head2->next);
}
return head;
}
算法的非递归实现如下:
Node *ListMerge(Node *head1,Node *head2)
{
if(!head1) return head2;
if(!head2) return head1;
Node *head=NULL;//合并后的头指针
Node *p1=head1;//p1用于扫描链表1
Node *p2=head2;//p2用于扫描链表2
if(head1->value<head2->value)
{
head=head1;
p1=head1->next;
}
else
{
head=head2;
p2=head2->next;
}
Node *p=head;//p永远指向最新合并的结点
while(p1 && p2)//如果循环停止,则p1或p2至少有一个为NULL
{
if(p1->value<p2->value)
{
p->next=p1;
p1=p1->next;
}
else
{
p->next=p2;
p2=p2->next;
}
p=p->next;
}
if(p1)//如果链1还没走完
{
p->next=p1;
}
else if(p2)//如果链2还没走完
{
p->next=p2;
}
return head;
}