剑指offer:6-重建二叉树
来源:互联网 发布:一分钟心理学 知乎 编辑:程序博客网 时间:2024/06/06 04:01
二叉树的遍历方式:前序、中序和后序。每种遍历均有递归和循环两种不同方法。递归实现要比循环简洁。
直接上代码:
二叉树节点结构:
(下面参考原书代码)
//BinaryTreeNode.h#ifndef BINARY_TREE_NODE_H#define BINARY_TREE_NODE_Hstruct BinaryTreeNode{int nValue;BinaryTreeNode *pLeftChild;BinaryTreeNode *pRightChild;};#endif
//BinaryTreeOperation.h#ifndef BINARY_TREE_OPERATION_H#define BINARY_TREE_OPERATION_H#include "BinaryTreeNode.h"//构造二进制树节点BinaryTreeNode *CreateBinaryTreeNode(int value);//连接树节点void ConnectTreeNodes(BinaryTreeNode *pParent,BinaryTreeNode *pLeftChild,BinaryTreeNode *pRightChild);//打印树节点void PrintTreeNode(BinaryTreeNode *pNode);//打印树void PrintTree(BinaryTreeNode *pRoot);//销毁树void DestroyTree(BinaryTreeNode *pRoot);#endif
//BinaryTreeOperation.cpp#include "BinaryTreeOperation.h"#include <iostream>using namespace std;//构造二进制树节点BinaryTreeNode *CreateBinaryTreeNode(int value){BinaryTreeNode *pNode = new BinaryTreeNode();pNode->nValue = value;pNode->pLeftChild = NULL;pNode->pRightChild = NULL;return pNode;}//连接树节点void ConnectTreeNodes(BinaryTreeNode *pParent,BinaryTreeNode *pLeftChild,BinaryTreeNode *pRightChild){if (pParent != NULL){pParent->pLeftChild = pLeftChild;pParent->pRightChild = pRightChild;}}//打印树节点void PrintTreeNode(BinaryTreeNode *pNode){if (pNode != NULL){cout << "value of this node is: " << pNode->nValue << endl;if (pNode->pLeftChild != NULL)cout << "value of its left child is: " << pNode->pLeftChild->nValue << endl;elsecout << "its left child is null.\n";if(pNode->pRightChild != NULL)cout << "value of its right child is: " << pNode->pRightChild->nValue << endl;elsecout << "its right child is null.\n";}elsecout << "this node is null.\n";cout << endl;}//打印树void PrintTree(BinaryTreeNode *pRoot){PrintTreeNode(pRoot);if (pRoot != NULL){if (pRoot->pLeftChild != NULL)PrintTree(pRoot->pLeftChild);if(pRoot->pRightChild != NULL)PrintTree(pRoot->pRightChild);}}//销毁树void DestroyTree(BinaryTreeNode *pRoot){if (pRoot != NULL){BinaryTreeNode *pLeft = pRoot->pLeftChild;BinaryTreeNode *pRight = pRoot->pRightChild;delete pRoot;pRoot = NULL;DestroyTree(pLeft);DestroyTree(pRight);}}
//main.cpp#include "BinaryTreeNode.h"#include "BinaryTreeOperation.h"#include <iostream>#include <exception>using namespace std;BinaryTreeNode *ConstructCore(int *startPreorder,int *endPreorder,int *strartInorder,int *endInorder){//前序遍历序列的第一个元素是根节点的值.int rootValue = startPreorder[0];BinaryTreeNode *root = new BinaryTreeNode();root->nValue = rootValue;root->pLeftChild = root->pRightChild = NULL;if (startPreorder == endPreorder){if(strartInorder == endInorder && *startPreorder == *strartInorder)return root;else throw exception("Invalid input!");}//在中序遍历中找到根节点的值.int *rootInorder = strartInorder;while(rootInorder <= endInorder && *rootInorder != rootValue)++rootInorder;if(rootInorder == endInorder && *rootInorder != rootValue)throw exception("Invalid input.");int leftLength = rootInorder - strartInorder;int *leftPreorderEnd = startPreorder + leftLength;//若左子树长度大于零,则存在左子树,构建左子树if (leftLength > 0)root->pLeftChild = ConstructCore(startPreorder + 1,leftPreorderEnd,strartInorder,rootInorder - 1);//若左子树长度小于总长度,则存在右子树,构建右子树if(leftLength < endPreorder - startPreorder)root->pRightChild = ConstructCore(leftPreorderEnd + 1,endPreorder,rootInorder+1,endInorder);return root;}BinaryTreeNode *Construct(int *preorder,int *inorder,int length){if(preorder == NULL ||inorder == NULL || length <= 0)return NULL;return ConstructCore(preorder,preorder + length -1,inorder,inorder + length - 1);}//=========================测试代码===========================void Test(char *testName,int *preorder,int *inorder,int length){if(testName != NULL)cout << "begins: " << testName << endl;cout << "the preorder sequence is: ";for (int i = 0;i < length;++i)cout << preorder[i] << " ";cout << endl << "the inorder sequence is: ";for (int i = 0;i < length;++i)cout << inorder[i] << " ";cout << endl;try{BinaryTreeNode *root = Construct(preorder,inorder,length);PrintTree(root);DestroyTree(root);}catch (exception& exception){cout << "Invalid Input.\n";}//cout << endl;}// 普通二叉树// 1// / \// 2 3 // / / \// 4 5 6// \ /// 7 8void Test1(){const int length = 8;int preorder[length] = {1, 2, 4, 7, 3, 5, 6, 8};int inorder[length] = {4, 7, 2, 1, 5, 3, 8, 6};Test("Test1", preorder, inorder, length);}// 所有结点都没有右子结点// 1// / // 2 // / // 3 // /// 4// /// 5void Test2(){const int length = 5;int preorder[length] = {1, 2, 3, 4, 5};int inorder[length] = {5, 4, 3, 2, 1};Test("Test2", preorder, inorder, length);}// 所有结点都没有左子结点// 1// \ // 2 // \ // 3 // \// 4// \// 5void Test3(){const int length = 5;int preorder[length] = {1, 2, 3, 4, 5};int inorder[length] = {1, 2, 3, 4, 5};Test("Test3", preorder, inorder, length);}// 树中只有一个结点void Test4(){const int length = 1;int preorder[length] = {1};int inorder[length] = {1};Test("Test4", preorder, inorder, length);}// 完全二叉树// 1// / \// 2 3 // / \ / \// 4 5 6 7void Test5(){const int length = 7;int preorder[length] = {1, 2, 4, 5, 3, 6, 7};int inorder[length] = {4, 2, 5, 1, 6, 3, 7};Test("Test5", preorder, inorder, length);}// 输入空指针void Test6(){Test("Test6", NULL, NULL, 0);}// 输入的两个序列不匹配void Test7(){const int length = 7;int preorder[length] = {1, 2, 4, 5, 3, 6, 7};int inorder[length] = {4, 2, 8, 1, 6, 3, 7};Test("Test7: for unmatched input", preorder, inorder, length);}int main(){Test1();Test2();Test3();Test4();Test5();Test6();Test7();return 0;}
运行结果如下:
最后构建的二叉树如下所示:
- 剑指offer:6-重建二叉树
- 剑指offer 6- 重建二叉树
- 剑指offer 6 重建二叉树
- 剑指Offer-6-重建二叉树
- 剑指Offer 6 重建二叉树
- 剑指offer---重建二叉树(6)
- [剑指offer]重建二叉树
- 【剑指offer】重建二叉树
- 剑指offer--重建二叉树
- 剑指offer---重建二叉树
- 剑指Offer-重建二叉树
- 剑指offer:重建二叉树
- 剑指offer-重建二叉树
- 《剑指offer》重建二叉树
- 【剑指Offer】重建二叉树
- 剑指offer-重建二叉树
- 《剑指offer》-重建二叉树
- 剑指offer 重建二叉树
- ASP数据库开发总结(ADO.NET小结)
- GB2312,GBK,Unicode
- 1
- BROWSEINFO结构体
- Matlab:任意矩阵计算分布密度(海明距离的分布密度)
- 剑指offer:6-重建二叉树
- NSTimer中调用静态方法
- tomcat session管理总结
- hdu 1062 字符串处理
- python tips(3)
- 比特币介绍和投资分析
- VirtualBox虚拟机网络设置(四种方式)
- 利用sql语句随机抽取记录
- samba ldap