#include <iostream>
#include <cstdlib>
template<typename T>
struct BTNode {
T data;
BTNode<T> *leftchild, *rightchild;
BTNode(): leftchild(NULL), rightchild(NULL) {}
BTNode(T x, BTNode<T> *l = NULL, BTNode<T> *r = NULL)
: data(x), leftchild(l), rightchild(r) {}
};
template<typename T>
class BTree {
public:
BTree(): root(NULL) {}
BTree(T value): refvalue(value), root(NULL) {}
BTree(BTree<T>& s);
~BTree() { destroy(root); }
bool is_empty() { return root == NULL; }
BTNode<T> *parent(BTNode<T> *current) {
return (root == NULL || root == current)? NULL: parent(root, current);
}
BTNode<T> *leftchild(BTNode<T> *current) {
return (current != NULL)? current->leftchild: NULL;
}
BTNode<T> *rightchild(BTNode<T> *current) {
return (current != NULL)? current->rightchild: NULL;
}
int height() const { return height(root); }
int size() const { return size(root); }
BTNode<T> *get_root() const { return root; }
void preorder(void (*visit)(BTNode<T> *p)) {
preorder(root, visit);
}
void inorder(void (*visit)(BTNode<T> *P)) {
inorder(root, visit);
}
void postorder(void (*visit)(BTNode<T> *p)) {
postorder(root, visit);
}
void levelorder(void (*visit)(BTNode<T> *P));
int insert(const T& x);
BTNode<T> *find(T& x) const;
protected:
BTNode<T> *root;
T refvalue;
void create_btree(std::istream& in, BTNode<T>*& subtree);
bool insert(BTNode<T>*& subtree, const T& x);
void destroy(BTNode<T>*& subtree);
bool find(BTNode<T> *subtree, const T& x) const;
BTNode<T> *copy(BTNode<T> *node);
int height(BTNode<T> *subtree) const;
int size(BTNode<T> *subtree) const;
BTNode<T> *parent(BTNode<T> *subtree, BTNode<T> *current);
BTNode<T> *find(BTNode<T> *subtree, const T& x) const;
void travel(BTNode<T> *subtree, std::ostream& out);
void preorder(BTNode<T>& subtree, void (*visit)(BTNode<T> *ptr));
void inorder(BTNode<T>& subtree, void (*visit)(BTNode<T> *ptr));
void postorder(BTNode<T>& subtree, void (*visit)(BTNode<T> *ptr));
friend std::istream& operator>>(std::istream& in, BTree<T>& tree);
friend std::istream& operator<<(std::istream& out, BTree<T>& tree);
};
template<typename T>
void BTree<T>::destroy(BTNode<T>*& subtree) {
if (subtree != NULL) {
destroy(subtree->leftchild);
destroy(subtree->rightchild);
delete subtree;
}
}
template<typename T>
BTNode<T> *BTree<T>::parent(BTNode<T> *subtree, BTNode<T> *current) {
if (subtree == NULL) return NULL;
if (subtree->leftchild == current || subtree->rightchild == current)
return subtree;
BTNode<T> *p;
if ((p = parent(subtree->leftchild, current)) != NULL)
return p;
else return parent(subtree->rightchild, current);
}
template<typename T>
void BTree<T>::travel(BTNode<T> *subtree, std::ostream& out) {
if (subtree != NULL) {
out << subtree->data << " ";
travel(subtree->leftchild, out);
travel(subtree->rightchild, out);
}
}
template<typename T>
std::istream& operator>>(std::istream& in, BTree<T>& tree) {
create_btree(in, tree.root);
return in;
}
template<typename T>
std::ostream& operator<<(std::ostream& out, BTree<T>& tree) {
out < " pre_oder travel\n ";
tree.travel(tree.root, out);
out << std::endl;
return out;
}
template<typename T>
void BTree<T>::inorder(BTNode<T>& subtree, void (*visit)(BTNode<T> *p)) {
if (subtree != NULL) {
inorder(subtree->leftchild, visit);
visit(subtree);
inorder(subtree->rightchild, visit);
}
}
template<typename T>
void BTree<T>::preorder(BTNode<T>& subtree, void (*visit)(BTNode<T> *p)) {
if (subtree != NULL) {
visit(subtree);
preorder(subtree->leftchild, visit);
preorder(subtree->rightchild, visit);
}
}
template<typename T>
void BTree<T>::postorder(BTNode<T>& subtree, void (*visit)(BTNode<T> *p)) {
if (subtree != NULL) {
postorder(subtree->leftchild, visit);
postorder(subtree->leftchild, visit);
visit(subtree);
}
}
template<typename T>
int BTree<T>::size(BTNode<T> *subtree) const {
if (subtree == NULL)
return 0;
else return 1 + size(subtree->leftchild) + size(subtree->rightchild);
}
template<typename T>
int BTree<T>::height(BTNode<T> *subtree) const {
if (subtree == NULL)
return 0;
else {
int i = height(subtree->leftchild);
int j = height(subtree->rightchild);
return (i < j)? j + 1: i + 1;
}
}
template<typename T>
BTNode<T> *BTree<T>::copy(BTNode<T> *node) {
if (node == NULL)
return NULL;
BTNode<T> *temp = new BTNode<T>;
temp->data = node->data;
temp->leftchild = copy(node->leftchild);
temp->rightchild = copy(node->rightchild);
return temp;
}
template<typename T>
BTree<T>::BTree(const BTree<T>& s) {
root = copy(s.root);
}
template<typename T>
int operator==(const BTree<T>& s, const BTree<T>& t) {
return equal(s.root, t.root);
}
template<typename T>
bool equal(BTNode<T> *a, BTNode<T> *b) {
if (a == NULL && b == NULL)
return true;
if (a != NULL && b != NULL && a->data == b->data
&& equal(a->leftchild, b->leftchild)
&& equal(a->rightchild, b->rightchild))
return true;
else return false;
}
// build a tree via preorder travel
template<typename T>
void BTree<T>::create_btree(std::istream& in, BTNode<T>*& subtree) {
T elem;
if (!in.eof()) {
in >> elem;
// terminate if refvalue = "#"
if (elem != refvalue) {
subtree = new BTNode<T>(elem);
if (!subtree) {
std::cerr << "memory alloc error !" << std::endl;
exit(1);
}
create_btree(in, subtree->leftchild);
create_btree(in, subtree->rightchild);
}
else subtree = NULL;
}
}
BinaryTree
最新推荐文章于 2025-05-09 22:15:14 发布