題目要求
Description
binary tree is a tree data structure in which each node has at most two children, which are referred to as the left child and the right child.
Three Constructor:
creat a tree by copy.
creat a tree by a array.(using BFS)
creat a tree by preorder and inorder.Methods:
clear: clear the tree.
copyTree: input old tree root and new tree root, copy get a new tree.
Static Methods:three way to search tree.
Hint
‘#’是表示该节点不存在,在下层判断的时候,可忽略该不存在的节点,主要在根据数组构造树中。
代碼實現
BinaryTree.hpp
//
// BinaryTree.hpp
// C++
//
// Created by 李天培 on 16/5/4.
// Copyright © 2016年 lee. All rights reserved.
//
#ifndef BinaryTree_hpp
#define BinaryTree_hpp
#include <iostream>
#include <vector>
#include <queue>
#include <stack>
#define EMPTY_ELE '#'
class BinaryTree {
public:
struct Node {
char val;
Node* left;
Node* right;
Node(char v, Node* l = NULL, Node* r = NULL):
val(v), left(l), right(r) {
}
};
BinaryTree(const BinaryTree&);
BinaryTree(std::vector<char>&);
// created by preorder and inorder
BinaryTree(const std::vector<char>& preOrder,
const std::vector<char>& inOrder);
~BinaryTree();
BinaryTree& operator=(const BinaryTree&);
Node* getRoot() const;
void clear();
static void preOrder(void (*visite)(BinaryTree::Node*), Node*);
static void inOrder(void (*visite)(BinaryTree::Node*), Node*);
static void postOrder(void (*visite)(BinaryTree::Node*), Node*);
private:
Node * copyNode(Node * oldNode, Node * newNode);
Node * root;
};
#endif
BinaryTree.cpp
#include<iostream>
#include"BinaryTree.hpp"
#include<vector>
using std::vector;
//assist function
BinaryTree::Node* BinaryTree::copyNode(Node *oldNode, Node *newNode) {
if (oldNode) {
newNode->val = oldNode->val;
newNode->left = new Node(oldNode->left->val, NULL, NULL);
newNode->right = new Node(oldNode->right->val, NULL, NULL);
}
return newNode;
}
void copyTree(BinaryTree::Node* Source_Root, BinaryTree::Node *&Target_Root) {
if (Source_Root == NULL) { // when use recursive , don't mistake 'while' for 'if'
Target_Root = NULL;
return;
}
Target_Root = new BinaryTree::Node(Source_Root->val);
copyTree(Source_Root->left, Target_Root->left);
copyTree(Source_Root->right, Target_Root->right);
}
//copy struct
BinaryTree::BinaryTree(const BinaryTree &tree) {
copyTree(tree.getRoot(), root);
}
//use two queue to build tree by BFS
BinaryTree::BinaryTree(std::vector<char> &arr) {
if (arr.size() == 0) {
root = NULL;
return;
}
std::vector<char>_ele(arr);
std::vector<Node*>parent;
while (_ele[0] == EMPTY_ELE)
_ele.erase(_ele.begin()); //the first ele might '#'
root = new Node(_ele[0], NULL, NULL);
parent.push_back(root);
_ele.erase(_ele.begin());
Node *current = parent[0];
for (; _ele.size() >= 2; current = parent[0]) {
if (current->val != EMPTY_ELE) {
current->left = new Node(_ele[0], NULL, NULL);
current->right = new Node(_ele[1], NULL, NULL);
parent.push_back(current->left);
parent.push_back(current->right);
_ele.erase(_ele.begin(), _ele.begin() + 2);
}
parent.erase(parent.begin());
}
if (_ele.size() == 1) {
while (current->val == EMPTY_ELE) { //maybe "#", should judge
parent.erase(parent.begin());
current = parent[0];
}
current->left = new Node(_ele[0], NULL, NULL);
}
}
//build tree by preorder and inorder use recursive
//some assist function
//strt, end, instrt, inEnd are all index
int search(vector<char>arr, int strt, int end, char value) {
int i;
for (i = strt; i <= end; ++i) {
if (arr[i] == value)
return i;
}
}
BinaryTree::Node* newNode(char data) {
BinaryTree::Node* temp = new BinaryTree::Node(data, NULL, NULL);
return temp;
}
BinaryTree::Node* buildTree(std::vector<char>in, std::vector<char>pre, int instrt, int inEnd) {
static int preIndex = 0;
if (instrt > inEnd)
return NULL;
BinaryTree::Node* tNode = newNode(pre[preIndex++]);
if (instrt == inEnd)
return tNode;
int inIndex = search(in, instrt, inEnd, tNode->val);
tNode->left = buildTree(in, pre, instrt, inIndex - 1);
tNode->right = buildTree(in, pre, inIndex + 1, inEnd);
return tNode;
}
BinaryTree::BinaryTree(const std::vector<char>& preOrder,
const std::vector<char>& inOrder) {
root = buildTree(inOrder, preOrder, 0, inOrder.size() - 1);
}
//destruct
BinaryTree::~BinaryTree() {
clear();
}
BinaryTree& BinaryTree::operator=(const BinaryTree &tree) {
if (root == tree.getRoot())
return *this;
clear();
copyTree(tree.getRoot(), root);
return *this;
}
BinaryTree::Node* BinaryTree::getRoot() const {
return root;
}
//assist function for delete
void deleteTree(BinaryTree::Node *_root) {
if (_root == NULL) return;
deleteTree(_root->left);
deleteTree(_root->right);
delete _root;
}
void BinaryTree::clear() {
deleteTree(root);
}
//static function
//visite is a function
void BinaryTree::preOrder(void(*visite)(BinaryTree::Node *temp), Node *_root) {
if (_root) {
if (_root->val != EMPTY_ELE)
visite(_root);
preOrder(visite, _root->left);
preOrder(visite, _root->right);
}
}
void BinaryTree::inOrder(void(*visite)(BinaryTree::Node *temp), Node *_root) {
if (_root) {
inOrder(visite, _root->left);
if (_root->val != EMPTY_ELE)
visite(_root);
inOrder(visite, _root->right);
}
}
void BinaryTree::postOrder(void(*visite)(BinaryTree::Node *temp), Node *_root){
if (_root) {
postOrder(visite, _root->left);
postOrder(visite, _root->right);
if (_root->val != EMPTY_ELE)
visite(_root);
}
}
main.cpp
#include <iostream>
#include "BinaryTree.hpp"
using namespace std;
void print(BinaryTree::Node * temp) {
cout << temp->val << " ";
}
std::vector<char> pre;
std::vector<char> in;
void getPreOrder(BinaryTree::Node * temp) {
pre.push_back(temp->val);
}
void getInOrder(BinaryTree::Node * temp) {
in.push_back(temp->val);
}
void testTree() {
cout << "test Tree" << endl;
int n = 1;
std::vector<char> tree;
cin >> n;
while (n--) {
char temp = '\0';
cin >> temp;
tree.push_back(temp);
}
BinaryTree x = BinaryTree(tree);
x = x;
BinaryTree::preOrder(print, x.getRoot());
cout << endl;
BinaryTree::inOrder(print, x.getRoot());
cout << endl;
BinaryTree::postOrder(print, x.getRoot());
cout << endl;
BinaryTree::preOrder(getPreOrder, x.getRoot());
BinaryTree::inOrder(getInOrder, x.getRoot());
BinaryTree t = BinaryTree(pre, in);
t = t;
BinaryTree::postOrder(print, t.getRoot());
cout << endl;
BinaryTree y = BinaryTree(t);
y = y;
BinaryTree::preOrder(print, y.getRoot());
cout << endl;
BinaryTree::inOrder(print, y.getRoot());
cout << endl;
BinaryTree::postOrder(print, y.getRoot());
BinaryTree::preOrder(getPreOrder, y.getRoot());
BinaryTree::inOrder(getInOrder, y.getRoot());
}
int main() {
testTree();
}
注意BinaryTree中的遞歸實現曾犯的錯誤