重建二叉树

来源:互联网 发布:手机转手绘软件 编辑:程序博客网 时间:2024/05/01 01:11

《编程之美》中的重建二叉树一题,文中所给方法自觉并非有“美”感。

我写了一个递归的方法。

1、每次递归只建立一个根节点,该根节点即为先序遍历的第一个字符,称为rootValue;

2、然后在中序遍历中找到rootValue,左边一段为左子树的中序遍历,右边一段为右子树的中序遍历;

3、根据中序遍历中rootValue的偏移量offset,可以在前序遍历找到左子树的前序遍历,和右子树的前序遍历;

如此,递归调用,即可完成。


#include <iostream>#include <assert.h>using namespace std;struct NODE {char value;NODE *leftChild;NODE *rightChild;};void preOrderTraverse (NODE *root){if(root == NULL)return;cout << root->value;preOrderTraverse(root->leftChild);preOrderTraverse(root->rightChild);}void inOrderTraverse (NODE *root){if(root == NULL)return;inOrderTraverse(root->leftChild);cout << root->value;inOrderTraverse(root->rightChild);}void postOrderTraverse (NODE *root){if(root == NULL)return;postOrderTraverse(root->leftChild);postOrderTraverse(root->rightChild);cout << root->value;}int getOffset(char *pInOrder, char rootValue,int begin, int end) {for(int i = begin; i <= end; ++i) {if(pInOrder[i] == rootValue){return i - begin;break;}}}NODE* build (char *pPreOrder, int preBegin, int preEnd,char *pInOrder,int inBegin, int inEnd) { NODE *root = new NODE;root->value = pPreOrder[preBegin];int rootOffset = getOffset(pInOrder, root->value, inBegin, inEnd);if(rootOffset > 0){root->leftChild = build(pPreOrder, preBegin + 1, preBegin + rootOffset,pInOrder, inBegin, inBegin + rootOffset - 1);}elseroot->leftChild = NULL;if(rootOffset < inEnd - inBegin){root->rightChild = build(pPreOrder, preBegin + rootOffset + 1, preEnd,pInOrder, inBegin + rootOffset + 1, inEnd);}elseroot->rightChild = NULL;return root;}void Rebuild (char *pPreOrder, char *pInOrder,int nTreeLength, NODE **pRoot){if(pPreOrder == NULL)cerr << "invalid input" << endl;*pRoot = build(pPreOrder, 0, nTreeLength - 1, pInOrder, 0, nTreeLength - 1);}int main(){char pPreOrder[] = "abcdefg";char pInOrder[] = "bcaedgf";NODE **pRoot = new NODE*;*pRoot = NULL;Rebuild(pPreOrder, pInOrder, 7, pRoot);cout << "pre_order: ";preOrderTraverse(*pRoot);cout << "\nin_order: ";inOrderTraverse(*pRoot);cout << "\npost_order: ";postOrderTraverse(*pRoot);cout << endl;return 0;}