#include<cstdio>
#include<iostream>
#include<cstdlib>
#include<cmath>
#include<stack>
#include<queue>
#include<stdbool.h>
#define stature(p) ((p)?(p)->height:-1)
#pragma once
using namespace std;
template<typename T>struct Visit
{
Visit(){}
void visit(T elem) { cout << elem << " "; }
void operator()(T elem) { visit(elem); }
};
template <typename T> struct bin_node;
template <typename T> using bin_node_posi = bin_node<T>*;
template <typename T> struct bin_node {
T data; bin_node_posi<T> parent, lchild, rchild; int height; int visited;
bin_node(T da, bin_node_posi<T> pa = NULL, bin_node_posi<T> lc = NULL,
bin_node_posi<T> rc = NULL, int h = 0, int v=0)
{
data = da; parent = pa; lchild = lc; rchild = rc; height = h; visited = 0;
}
int get_size();
bin_node_posi<T> insert_as_left_child(const T& elem);
bin_node_posi<T> insert_as_right_child(const T& elem);
bin_node_posi<T> success();
template<typename VST>void tra_preorder(VST&);
template<typename VST>void tra_inorder(VST&);
template<typename VST>void tra_postorder(VST&);
template<typename VST>void tra_levelorder(VST&);
};
template<typename T> int bin_node<T>::get_size()
{
if (this == NULL)
return 0;
return lchild->get_size() + rchild->get_size() + 1;
}
template<typename T> bin_node_posi<T> bin_node<T>::insert_as_left_child(const T& elem)
{
bin_node<T> temp(elem, this);
lchild = temp;
return lchild;
}
template<typename T> bin_node_posi<T> bin_node<T>::insert_as_right_child(const T& elem)
{
bin_node<T> temp(elem, this);
rchild = temp;
return rchild;
}
template<typename T> bin_node_posi<T> bin_node<T>::success()
{
bin_node_posi<T> node_s = this;
if (node_s->rchild)
{
bin_node_posi<T> temp = node_s->rchild;
while (temp->lchild)
temp = temp->lchild;
return temp;
}
else
{
bin_node_posi<T> parnt = node_s->parent;
while (parnt != NULL && parnt->lchild != node_s) {
node_s = node_s->parent;
parnt = node_s->parent;
}
return parnt;
}
}
template<typename T> template<typename VST>
void bin_node<T>::tra_preorder(VST& visit)
{
pre_order_tra(this, visit);
cout << endl;
}
template<typename T> template<typename VST>
void bin_node<T>::tra_inorder(VST& visit)
{
in_order_tra(this, visit);
cout << endl;
}
template<typename T> template<typename VST>
void bin_node<T>::tra_postorder(VST& visit)
{
post_order_tra(this, visit);
cout << endl;
}
template<typename T> template<typename VST>
void bin_node<T>::tra_levelorder(VST& visit)
{
level_order_tra(this, visit);
cout << endl;
}
template<typename T, typename VST>
void visit_along_left_vine(bin_node_posi<T> node_pos, VST& visit, stack< bin_node_posi<T>>& stk)
{
while (node_pos) {
visit(node_pos->data);
if (node_pos->rchild) stk.push(node_pos->rchild);
node_pos = node_pos->lchild;
}
}
template<typename T, typename VST> void pre_order_tra(bin_node_posi<T> node_pos, VST& visit)
{
stack<bin_node_posi<T>> stk;
do {
visit_along_left_vine(node_pos, visit, stk);
if (stk.empty())
break;
node_pos = stk.top();
stk.pop();
} while (1);
}
template<typename T> void go_along_left_vine(bin_node_posi<T> node_pos, stack<bin_node_posi<T>>& stk)
{
while (node_pos)
{
stk.push(node_pos);
node_pos = node_pos->lchild;
}
}
template<typename T, typename VST>
void in_order_tra(bin_node_posi<T> node_pos, VST& visit)
{
stack<bin_node_posi<T>> stk;
do {
go_along_left_vine(node_pos, stk);
if (stk.empty())
break;
bin_node_posi<T> temp = stk.top();
stk.pop();
visit(temp->data);
node_pos = temp->rchild;
} while (1);
}
template<typename T>
void go_left_most_leaf(bin_node_posi<T> node_pos, stack<bin_node_posi<T> >& stk)
{
while (node_pos)
{
stk.push(node_pos);
if (node_pos->lchild) node_pos = node_pos->lchild;
else if (node_pos->rchild) node_pos = node_pos->rchild;
else break;
}
}
template<typename T, typename VST>
void post_order_tra(bin_node_posi<T> node_pos, VST& visit)
{
stack<bin_node_posi<T>> stk;
go_left_most_leaf(node_pos, stk);
while (!stk.empty())
{
bin_node_posi<T> node_temp = stk.top();
visit(node_temp->data);
node_temp->visited = 1;
stk.pop();
if (stk.empty())break;
if (stk.top()->rchild != NULL && stk.top()->rchild->visited != 1)
{
go_left_most_leaf(stk.top()->rchild, stk);
}
}
}
template<typename T, typename VST>
void level_order_tra(bin_node_posi<T> node_pos, VST& visit)
{
queue<bin_node_posi<T>> Queue;
Queue.push(node_pos);
while (!Queue.empty())
{
bin_node_posi<T> temp = Queue.front();
visit(temp->data);
Queue.pop();
if (temp->lchild) Queue.push(temp->lchild);
if (temp->rchild) Queue.push(temp->rchild);
}
}
template<typename T>class bin_tree {
private:
int size; bin_node_posi<T> root;
public:
bin_tree(int sz = 0, bin_node_posi<T> rt = NULL) :size(sz), root(rt) {}
~bin_tree()
{
if (size > 0)
remove(root);
}
int get_size() { return size; }
bin_node_posi<T> get_root() { return root; }
bool empty() { return !root; }
virtual int update_height(bin_node_posi<T> node_pos);
void update_height_above(bin_node_posi<T> node_pos);
bin_node_posi<T> insert_as_root(const T&);
bin_node_posi<T> insert_as_lc(const T&, bin_node_posi<T> node_pos);
bin_node_posi<T> insert_as_rc(bin_node_posi<T> node_pos, const T&);
bin_node_posi<T> attached_as_lc(bin_tree<T>*& subtree, bin_node_posi<T> node_pos);
bin_node_posi<T> attached_as_rc(bin_node_posi<T> node_pos, bin_tree<T>*& subtree);
int remove(bin_node_posi<T> node_pos);
bin_tree<T>* secede(bin_node_posi<T> node);
template<typename VST> void preorder_tra(VST& visit) { if(root) root->tra_preorder; }
template<typename VST> void inorder_tra(VST& visit) { if (root) root->tra_inorder; }
template<typename VST> void postorder_tra(VST& visit) { if (root) root->tra_postorder; }
template<typename VST> void levelorder_tra(VST& visit) { if (root) root->tra_levelorder; }
};
template<typename T>struct Release;
template<typename T>struct Release<T*>
{
static void _release(T* elem)
{
if (elem)
delete elem;
}
};
template<typename T>struct Release
{
static void _release(T elem) {}
};
template<typename T>void release(T elem)
{
Release<T>::_release(elem);
}
template<typename T> static int remove_at(bin_node_posi<T> node_pos)
{
if (!node_pos) return 0;
int size = 1 + remove_at(node_pos->lchild) + remove_at(node_pos->rchild);
release(node_pos->data); release(node_pos);
return size;
}
template<typename T> int bin_tree<T>::update_height(bin_node_posi<T> node_pos)
{
return max(stature(node_pos->lchild), stature(node_pos->rchild)) + 1;
}
template<typename T> void bin_tree<T>::update_height_above(bin_node_posi<T> node_pos)
{
while (node_pos) {
update_height(node_pos);
node_pos = node_pos->parent;
}
}
template<typename T> bin_node_posi<T> bin_tree<T>::insert_as_root(const T& elem)
{
++size;
root = new bin_node<T>(elem);
return root;
}
template<typename T> bin_node_posi<T> bin_tree<T>::insert_as_lc(const T& elem, bin_node_posi<T> node_pos)
{
node_pos->insert_as_left_child(elem);
size++;
update_height_above(node_pos);
return node_pos->lchild;
}
template<typename T> bin_node_posi<T> bin_tree<T>::insert_as_rc(bin_node_posi<T> node_pos, const T& elem)
{
node_pos->insert_as_right_child(elem);
size++;
update_height_above(node_pos);
return node_pos->rchild;
}
template<typename T> bin_node_posi<T> bin_tree<T>::attached_as_lc(bin_tree<T>*& subtree, bin_node_posi<T> node_pos)
{
if (subtree->root = node_pos)
node_pos->lchild = subtree->root;
size += subtree->size;
update_height_above(node_pos);
subtree->root = NULL;
subtree->size = 0;
release(subtree);
subtree = NULL;
return node_pos->lchild;
}
template<typename T> bin_node_posi<T> bin_tree<T>::attached_as_rc(bin_node_posi<T> node_pos, bin_tree<T>*& subtree)
{
if (subtree->root = node_pos)
node_pos->rchild = subtree->root;
size += subtree->size;
update_height_above(node_pos);
subtree->root = NULL;
subtree->size = 0;
release(subtree);
subtree = NULL;
return node_pos->rchild;
}
template<typename T> int bin_tree<T>::remove(bin_node_posi<T> node_pos)
{
int sub_size = 0;
if (bin_node_posi<T> parent = node_pos->parent)
{
if (parent->lchild == node_pos)
parent->lchild = NULL;
else
parent->rchild = NULL;
update_height_above(parent);
sub_size = remove_at(node_pos);
size -= sub_size;
}
return sub_size;
}
template<typename T> bin_tree<T>* bin_tree<T>::secede(bin_node_posi<T> node)
{
if (bin_node_posi<T> parent = node->parent)
{
if (parent->lchild == node)
parent->lchild = NULL;
else
parent->rchild = NULL;
int sz = node->get_size();
size -= sz;
update_hight_above(parent);
bin_tree<T>* subtree_ptr = new bin_tree<T>;
subtree_ptr->size = sz;
subtree_ptr->root = node;
subtree_ptr->root = NULL;
return subtree_ptr;
}
else {
return this;
}
}
#include"bin_tree.h"
FILE* fp;
template<typename T> void preorder_create(bin_node_posi<T>& root,FILE* fp)
{
T elem;
int size = 0;
fscanf(fp, "%c", &elem);
if (elem == '#')
return;
root = new bin_node<T>(elem);
preorder_create(root->lchild,fp);
preorder_create(root->rchild,fp);
}
int main()
{
bin_node_posi<char> root = NULL;
fp = fopen("tree.txt", "r");
preorder_create(root,fp);
Visit<char> visit;
cout << "层序遍历" << endl;
root->tra_levelorder(visit);
cout << "先序遍历" << endl;
root->tra_preorder(visit);
cout << "中序遍历" << endl;
root->tra_inorder(visit);
cout << "后序遍历" << endl;
root->tra_postorder(visit);
int size = root->get_size();
bin_tree<char>* btree = new bin_tree<char>(size, root);
}
![在这里插入图片描述](https://i-blog.csdnimg.cn/blog_migrate/bd3b4bc532a70d1a821820f2bfcaacd0.png)