重建二叉树

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

我写了一个递归的方法。

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);
		}
		else
			root->leftChild = NULL;

		if(rootOffset < inEnd - inBegin){
			root->rightChild = build(pPreOrder, preBegin + rootOffset + 1, preEnd,
				pInOrder, inBegin + rootOffset + 1, inEnd);
		}
		else
			root->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;
}


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值