剑指Offer----面试题19:二叉树的镜像

题目


请完成一个函数,输入一个二叉树,该函数输出它的镜像。

方法一:


分析:镜像无非就是让二叉树每一个结点的左孩子和右孩子交换位置,显然,这要用到递归的知识。

源代码如下:

#include"BinaryTree.h"
#include<iostream>

using std::cout;
using std::endl;

using namespace OrdinaryBinaryTreeSpace3;

BinaryTreeNode *Total(BinaryTreeNode *root);
void Change(BinaryTreeNode *root);

BinaryTreeNode *Total(BinaryTreeNode *root)
{
	if (root == NULL)
	{
		cout << "二叉树为空,无法求其镜像" << endl;
		return NULL;
	}

	if (root != NULL && (root)->left == NULL && (root)->right == NULL)
	{
		cout << "只有一个结点,不用求其镜像" << endl;
		return NULL;
	}

	Change(root);

	return root;

}

void Change(BinaryTreeNode *root)
{
	if (root == NULL)
		return;

	if ((root)->left == NULL && (root)->right == NULL)
		return;

	BinaryTreeNode *left_temp = (root)->left;
	BinaryTreeNode *right_temp = (root)->right;

	(root)->left = right_temp;
	(root)->right = left_temp;

	Change((root)->left);
	Change((root)->right);
}

/*
		9						9
	   / \		转换之后	   / \
      8   2					  2   8
*/
void test11()
{
	cout << "===========简单满二叉树的镜像==============" << endl;
	BinaryTreeNode *node1 = CreateBinaryTreeNode(8);
	BinaryTreeNode *node2 = CreateBinaryTreeNode(9);
	BinaryTreeNode *node3 = CreateBinaryTreeNode(2);
	ConnectBinaryTreeNodes(node1, node2, node3);
	ConnectBinaryTreeNodes(node2, NULL, NULL);
	ConnectBinaryTreeNodes(node3, NULL, NULL);

	cout << "Before change:";
	PrintTreeMid(node1);
	Total(node1);
	cout << "\nAfter  change:";
	PrintTreeMid(node1);
	cout << endl;
}

/*
			8									8
           / \								   / \	
          6   10		转换之后			 10   6
		 / \  / \							/ \  / \ 
		5  7 9  11						   11 9  7  5	
*/

void test12()
{
	cout << "===========复杂满二叉树的镜像==============" << endl;
	BinaryTreeNode *node1 = CreateBinaryTreeNode(8);
	BinaryTreeNode *node2 = CreateBinaryTreeNode(6);
	BinaryTreeNode *node3 = CreateBinaryTreeNode(10);
	BinaryTreeNode *node4 = CreateBinaryTreeNode(5);
	BinaryTreeNode *node5 = CreateBinaryTreeNode(7);
	BinaryTreeNode *node6 = CreateBinaryTreeNode(9);
	BinaryTreeNode *node7 = CreateBinaryTreeNode(11);
	ConnectBinaryTreeNodes(node1, node2, node3);
	ConnectBinaryTreeNodes(node2, node4, node5);
	ConnectBinaryTreeNodes(node3, node6, node7);
	ConnectBinaryTreeNodes(node4, NULL, NULL);
	ConnectBinaryTreeNodes(node5, NULL, NULL);
	ConnectBinaryTreeNodes(node6, NULL, NULL);
	ConnectBinaryTreeNodes(node7, NULL, NULL);

	cout << "Before change:";
	PrintTreeMid(node1);
	Total(node1);
	cout << "\nAfter  change:";
	PrintTreeMid(node1);
	cout << endl;
}

void test13()
{
	cout << "===========空二叉树的镜像==============" << endl;
	Total(NULL);
}

void test14()
{
	cout << "===========只有一个父节点二叉树的镜像==============" << endl;
	BinaryTreeNode *node1 = CreateBinaryTreeNode(8);
	ConnectBinaryTreeNodes(node1, NULL, NULL);

	cout << "Before change:";
	PrintTreeMid(node1);
	Total(node1);
	cout << "\nAfter  change:";
	PrintTreeMid(node1);
	cout << endl;
}

/*
						1								1
					   /								 \
					  2									  2
					 /									   \
					3										3
				   /										 \
				  4					转换之后				  4
				 /											   \
				5												5
			   /												 \
			  6													  6
			 /													   \
			7													    7
*/

void test15()
{
	cout << "===========只有左孩子二叉树的镜像==============" << endl;
	BinaryTreeNode *node1 = CreateBinaryTreeNode(1);
	BinaryTreeNode *node2 = CreateBinaryTreeNode(2);
	BinaryTreeNode *node3 = CreateBinaryTreeNode(3);
	BinaryTreeNode *node4 = CreateBinaryTreeNode(4);
	BinaryTreeNode *node5 = CreateBinaryTreeNode(5);
	BinaryTreeNode *node6 = CreateBinaryTreeNode(6);
	BinaryTreeNode *node7 = CreateBinaryTreeNode(7);
	ConnectBinaryTreeNodes(node1, node2, NULL);
	ConnectBinaryTreeNodes(node2, node3, NULL);
	ConnectBinaryTreeNodes(node3, node4, NULL);
	ConnectBinaryTreeNodes(node4, node5, NULL);
	ConnectBinaryTreeNodes(node5, node6, NULL);
	ConnectBinaryTreeNodes(node6, node7, NULL);
	ConnectBinaryTreeNodes(node7, NULL, NULL);

	cout << "Before change:";
	PrintTreeMid(node1);
	Total(node1);
	cout << "\nAfter  change:";
	PrintTreeMid(node1);
	cout << endl;
}

void test16()
{
	cout << "===========只有右孩子二叉树的镜像==============" << endl;
	BinaryTreeNode *node1 = CreateBinaryTreeNode(1);
	BinaryTreeNode *node2 = CreateBinaryTreeNode(2);
	BinaryTreeNode *node3 = CreateBinaryTreeNode(3);
	BinaryTreeNode *node4 = CreateBinaryTreeNode(4);
	BinaryTreeNode *node5 = CreateBinaryTreeNode(5);
	BinaryTreeNode *node6 = CreateBinaryTreeNode(6);
	BinaryTreeNode *node7 = CreateBinaryTreeNode(7);
	ConnectBinaryTreeNodes(node1, NULL, node2);
	ConnectBinaryTreeNodes(node2, NULL, node3);
	ConnectBinaryTreeNodes(node3, NULL, node4);
	ConnectBinaryTreeNodes(node4, NULL, node5);
	ConnectBinaryTreeNodes(node5, NULL, node6);
	ConnectBinaryTreeNodes(node6, NULL, node7);
	ConnectBinaryTreeNodes(node7, NULL, NULL);

	cout << "Before change:";
	PrintTreeMid(node1);
	Total(node1);
	cout << "\nAfter  change:";
	PrintTreeMid(node1);
	cout << endl;
}

int main()
{
	test11();
	cout << endl;
	test12();
	cout << endl;
	test13();
	cout << endl;
	test14();
	cout << endl;
	test15();
	cout << endl;
	test16();
	cout << endl;

	system("pause");
	return 0;
}

运行结果:
===========简单满二叉树的镜像==============
Before change:9  8  2
After  change:2  8  9

===========复杂满二叉树的镜像==============
Before change:5  6  7  8  9  10  11
After  change:11  10  9  8  7  6  5

===========空二叉树的镜像==============
二叉树为空,无法求其镜像

===========只有一个父节点二叉树的镜像==============
Before change:8  只有一个结点,不用求其镜像

After  change:8

===========只有左孩子二叉树的镜像==============
Before change:7  6  5  4  3  2  1
After  change:1  2  3  4  5  6  7

===========只有右孩子二叉树的镜像==============
Before change:1  2  3  4  5  6  7
After  change:7  6  5  4  3  2  1

请按任意键继续. . .

注意:题目中提到要用一个函数,而非两个函数。

方法二:

官方源代码:
#include"BinaryTree.h"
#include<cstdlib>
#include<cstdio>
#include<stack>

using namespace OrdinaryBinaryTreeSpace3;

void MirrorRecursively(BinaryTreeNode *pNode)
{
	if ((pNode == NULL) || (pNode->left == NULL && pNode->right == NULL))
		return;

	BinaryTreeNode *pTemp = pNode->left;
	pNode->left = pNode->right;
	pNode->right = pTemp;

	if (pNode->left)
		MirrorRecursively(pNode->left);

	if (pNode->right)
		MirrorRecursively(pNode->right);
}

void MirrorIteratively(BinaryTreeNode* pRoot)
{
	if (pRoot == NULL)
		return;

	std::stack<BinaryTreeNode*> stackTreeNode;
	stackTreeNode.push(pRoot);

	while (stackTreeNode.size() > 0)
	{
		BinaryTreeNode *pNode = stackTreeNode.top();
		stackTreeNode.pop();

		BinaryTreeNode *pTemp = pNode->left;
		pNode->left = pNode->right;
		pNode->right = pTemp;

		if (pNode->left)
			stackTreeNode.push(pNode->left);

		if (pNode->right)
			stackTreeNode.push(pNode->right);
	}
}

// ====================测试代码====================
// 测试完全二叉树:除了叶子节点,其他节点都有两个子节点
//            8
//        6      10
//       5 7    9  11
void Test1()
{
	printf("=====Test1 starts:=====\n");
	BinaryTreeNode* pNode8 = CreateBinaryTreeNode(8);
	BinaryTreeNode* pNode6 = CreateBinaryTreeNode(6);
	BinaryTreeNode* pNode10 = CreateBinaryTreeNode(10);
	BinaryTreeNode* pNode5 = CreateBinaryTreeNode(5);
	BinaryTreeNode* pNode7 = CreateBinaryTreeNode(7);
	BinaryTreeNode* pNode9 = CreateBinaryTreeNode(9);
	BinaryTreeNode* pNode11 = CreateBinaryTreeNode(11);

	ConnectBinaryTreeNodes(pNode8, pNode6, pNode10);
	ConnectBinaryTreeNodes(pNode6, pNode5, pNode7);
	ConnectBinaryTreeNodes(pNode10, pNode9, pNode11);

	PrintTreeMid(pNode8);

	printf("=====Test1: MirrorRecursively=====\n");
	MirrorRecursively(pNode8);
	PrintTreeMid(pNode8);

	printf("=====Test1: MirrorIteratively=====\n");
	MirrorIteratively(pNode8);
	PrintTreeMid(pNode8);

	DestoryTree(pNode8);
}

// 测试二叉树:出叶子结点之外,左右的结点都有且只有一个左子结点
//            8
//          7   
//        6 
//      5
//    4
void Test2()
{
	printf("=====Test2 starts:=====\n");
	BinaryTreeNode* pNode8 = CreateBinaryTreeNode(8);
	BinaryTreeNode* pNode7 = CreateBinaryTreeNode(7);
	BinaryTreeNode* pNode6 = CreateBinaryTreeNode(6);
	BinaryTreeNode* pNode5 = CreateBinaryTreeNode(5);
	BinaryTreeNode* pNode4 = CreateBinaryTreeNode(4);

	ConnectBinaryTreeNodes(pNode8, pNode7, NULL);
	ConnectBinaryTreeNodes(pNode7, pNode6, NULL);
	ConnectBinaryTreeNodes(pNode6, pNode5, NULL);
	ConnectBinaryTreeNodes(pNode5, pNode4, NULL);

	PrintTreeMid(pNode8);

	printf("=====Test2: MirrorRecursively=====\n");
	MirrorRecursively(pNode8);
	PrintTreeMid(pNode8);

	printf("=====Test2: MirrorIteratively=====\n");
	MirrorIteratively(pNode8);
	PrintTreeMid(pNode8);

	DestoryTree(pNode8);
}

// 测试二叉树:出叶子结点之外,左右的结点都有且只有一个右子结点
//            8
//             7   
//              6 
//               5
//                4
void Test3()
{
	printf("=====Test3 starts:=====\n");
	BinaryTreeNode* pNode8 = CreateBinaryTreeNode(8);
	BinaryTreeNode* pNode7 = CreateBinaryTreeNode(7);
	BinaryTreeNode* pNode6 = CreateBinaryTreeNode(6);
	BinaryTreeNode* pNode5 = CreateBinaryTreeNode(5);
	BinaryTreeNode* pNode4 = CreateBinaryTreeNode(4);

	ConnectBinaryTreeNodes(pNode8, NULL, pNode7);
	ConnectBinaryTreeNodes(pNode7, NULL, pNode6);
	ConnectBinaryTreeNodes(pNode6, NULL, pNode5);
	ConnectBinaryTreeNodes(pNode5, NULL, pNode4);

	PrintTreeMid(pNode8);

	printf("=====Test3: MirrorRecursively=====\n");
	MirrorRecursively(pNode8);
	PrintTreeMid(pNode8);

	printf("=====Test3: MirrorIteratively=====\n");
	MirrorIteratively(pNode8);
	PrintTreeMid(pNode8);

	DestoryTree(pNode8);
}

// 测试空二叉树:根结点为空指针
void Test4()
{
	printf("=====Test4 starts:=====\n");
	BinaryTreeNode* pNode = NULL;

	PrintTreeMid(pNode);

	printf("=====Test4: MirrorRecursively=====\n");
	MirrorRecursively(pNode);
	PrintTreeMid(pNode);

	printf("=====Test4: MirrorIteratively=====\n");
	MirrorIteratively(pNode);
	PrintTreeMid(pNode);
}

// 测试只有一个结点的二叉树
void Test5()
{
	printf("=====Test5 starts:=====\n");
	BinaryTreeNode* pNode8 = CreateBinaryTreeNode(8);

	PrintTreeMid(pNode8);

	printf("=====Test4: MirrorRecursively=====\n");
	MirrorRecursively(pNode8);
	PrintTreeMid(pNode8);

	printf("=====Test4: MirrorIteratively=====\n");
	MirrorIteratively(pNode8);
	PrintTreeMid(pNode8);
}

int main()
{
	Test1();
	putchar('\n');
	Test2();
	putchar('\n');
	Test3();
	putchar('\n');
	Test4();
	putchar('\n');
	Test5();
	putchar('\n');

	system("pause");
	return 0;
}

运行结果:
=====Test1 starts:=====
5  6  7  8  9  10  11  =====Test1: MirrorRecursively=====
11  10  9  8  7  6  5  =====Test1: MirrorIteratively=====
5  6  7  8  9  10  11
=====Test2 starts:=====
4  5  6  7  8  =====Test2: MirrorRecursively=====
8  7  6  5  4  =====Test2: MirrorIteratively=====
4  5  6  7  8
=====Test3 starts:=====
8  7  6  5  4  =====Test3: MirrorRecursively=====
4  5  6  7  8  =====Test3: MirrorIteratively=====
8  7  6  5  4
=====Test4 starts:=====
The tree is empty
=====Test4: MirrorRecursively=====
The tree is empty
=====Test4: MirrorIteratively=====
The tree is empty

=====Test5 starts:=====
8  =====Test4: MirrorRecursively=====
8  =====Test4: MirrorIteratively=====
8
请按任意键继续. . .


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值