BinaryTree.h
#ifndef BINARYTREE_H
#define BINARYTREE_H
#include<iostream>
#include<stack>
#include<queue>
//binary tree node
struct binary_tree_node{
char data;
binary_tree_node* lchild;
binary_tree_node* rchild;
binary_tree_node() :lchild(NULL), rchild(NULL){}
binary_tree_node(char ch) :data(ch), lchild(NULL), rchild(NULL){}
};
//BinaryTree
class BinaryTree{
public:
typedef binary_tree_node node_value;
typedef binary_tree_node* node_pointer;
BinaryTree();
~BinaryTree();
node_pointer get_root();
void create_preorder(node_pointer& p);
void preorder_recursive(node_pointer p);
void inorder_recursive(node_pointer p);
void postorder_recursive(node_pointer p);
void preorder_no_recursive(node_pointer p);
void preorder_no_recursive2(node_pointer p);
void inorder_no_recursive(node_pointer p);
void postorder_no_recursive(node_pointer p);
void levelorder(node_pointer p);
void tree_depth(node_pointer p, int& depth, int level);
int leaf_count(node_pointer p);
int node_count(node_pointer p);
private:
void destroy(node_pointer p);
private:
node_pointer root;
};
BinaryTree::BinaryTree() :root(NULL){}
BinaryTree::~BinaryTree(){
destroy(root);
root = NULL;
}
void BinaryTree::destroy(node_pointer p){
if (p == NULL)
return;
destroy(p->lchild);
destroy(p->rchild);
delete p;
}
BinaryTree::node_pointer BinaryTree::get_root(){
return root;
}
void BinaryTree::create_preorder(node_pointer& p){
char ch;
std::cin >> ch;
if (ch == '#')
p = NULL;
else{
p = new node_value(ch);
create_preorder(p->lchild);
create_preorder(p->rchild);
}
}
void BinaryTree::preorder_recursive(node_pointer p){
if (p == NULL)
return;
std::cout << p->data << ' ';
preorder_recursive(p->lchild);
preorder_recursive(p->rchild);
}
void BinaryTree::inorder_recursive(node_pointer p){
if (p == NULL)
return;
inorder_recursive(p->lchild);
std::cout << p->data << ' ';
inorder_recursive(p->rchild);
}
void BinaryTree::postorder_recursive(node_pointer p){
if (p == NULL)
return;
postorder_recursive(p->lchild);
postorder_recursive(p->rchild);
std::cout << p->data << ' ';
}
/*
先让根进栈,只要栈不为空,就可以做弹出操作,
每次弹出一个结点,就把它的右孩子和左孩子依次入栈,这样可以保证右子树在栈中总处于左子树的下面。
*/
void BinaryTree::preorder_no_recursive(node_pointer p){
if (p == NULL)
return;
std::stack<node_pointer> stk;
stk.push(p);
while (!stk.empty()){
node_pointer cur = stk.top();
std::cout << cur->data << ' ';
stk.pop();
if (cur->rchild)
stk.push(cur->rchild);
if (cur->lchild)
stk.push(cur->lchild);
}
}
/*
对于任一结点P:
1)访问结点P,并将结点P入栈;
2)判断结点P的左孩子是否为空,若为空,则取栈顶结点并进行出栈操作,并将栈顶结点的右孩子置为当前的结点P,循环至1);
若不为空,则将P的左孩子置为当前的结点P;
3)直到P为NULL并且栈为空,则遍历结束。
*/
void BinaryTree::preorder_no_recursive2(node_pointer p){
if (p == NULL)
return;
std::stack<node_pointer> stk;
node_pointer cur = p;
while (cur != NULL || !stk.empty()){
while (cur != NULL){
std::cout << cur->data << ' ';
stk.push(cur);
cur = cur->lchild;
}
if (!stk.empty()){
cur = stk.top();
stk.pop();
cur = cur->rchild;
}
}
}
/*
对于任一结点P,
1)若其左孩子不为空,则将P入栈并将P的左孩子置为当前的P,然后对当前结点P再进行相同的处理;
2)若其左孩子为空,则取栈顶元素并进行出栈操作,访问该栈顶结点,然后将当前的P置为栈顶结点的右孩子;
3)直到P为NULL并且栈为空则遍历结束
*/
void BinaryTree::inorder_no_recursive(node_pointer p){
if (p == NULL)
return;
std::stack<node_pointer> stk;
node_pointer cur = p;
while (cur != NULL || !stk.empty()){
while (cur != NULL){
stk.push(cur);
cur = cur->lchild;
}
if (!stk.empty()){
cur = stk.top();
std::cout << cur->data << ' ';
stk.pop();
cur = cur->rchild;
}
}
}
/*
对于任一结点P,先将其入栈。如果P不存在左孩子和右孩子,则可以直接访问它;
或者P存在左孩子或者右孩子,但是其左孩子和右孩子都已被访问过了,也可以直接访问它。
若非上述两种情况,则将P的右孩子和左孩子依次入栈,这样就保证了
左孩子在右孩子前面被访问,左孩子和右孩子都在根结点前面被访问。
*/
void BinaryTree::postorder_no_recursive(node_pointer p){
if (p == NULL)
return;
std::stack<node_pointer> stk;
stk.push(p);
node_pointer cur;
node_pointer pre = NULL;
while (!stk.empty()){
cur = stk.top();
if ((cur->lchild == NULL&&cur->rchild == NULL) || pre != NULL && (cur->lchild == pre || cur->rchild == pre)){
std::cout << cur->data << ' ';
stk.pop();
pre = cur;
}
else{
if (cur->rchild)
stk.push(cur->rchild);
if (cur->lchild)
stk.push(cur->lchild);
}
}
}
/*
先让根进队列,只要队列不为空,就可以做pop操作,
每次pop一个结点,就把它的左孩子和右孩子依次入队列,这样可以保证层次遍历。
*/
void BinaryTree::levelorder(node_pointer p){
if (p == NULL)
return;
std::queue<node_pointer> que;
que.push(p);
while (!que.empty()){
node_pointer temp = que.front();
std::cout << temp->data << ' ';
if (temp->lchild)
que.push(temp->lchild);
if (temp->rchild)
que.push(temp->rchild);
que.pop();
}
}
void BinaryTree::tree_depth(node_pointer p, int& depth, int level){
if (p == NULL)
return;
if (level>depth)
depth = level;
tree_depth(p->lchild, depth, level + 1);
tree_depth(p->rchild, depth, level + 1);
}
int BinaryTree::leaf_count(node_pointer p){
if (p == NULL)
return 0;
else if (p->lchild == NULL&&p->rchild == NULL)
return 1;
else
return (leaf_count(p->lchild) + leaf_count(p->rchild));
}
int BinaryTree::node_count(node_pointer p){
if (p == NULL)
return 0;
else
return (1 + node_count(p->lchild) + node_count(p->rchild));
}
#endif
main.cpp
#include"BinaryTree.h"
using namespace std;
void menu(){
cout << "========================================================================" << endl;
cout << "1.输入字符序列,以先序序列建立二叉树!" << endl;
cout << "2.先序、中序、后序遍历二叉树(递归算法)!" << endl;
cout << "3.先序、中序、后序遍历二叉树(非递归算法)!" << endl;
cout << "4.层次遍历二叉树!" << endl;
cout << "5.求二叉树的高度!" << endl;
cout << "6.求二叉树的叶子个数!" << endl;
cout << "7.求二叉树的节点个数!" << endl;
cout << "0.退出程序!" << endl;
cout << "========================================================================" << endl;
}
int main(){
int choose;
int depth;
int level;
bool flag = true;
BinaryTree binary_tree;
binary_tree_node* root = binary_tree.get_root();
while (flag){
menu();
cout << "请输入要选择的功能:";
cin >> choose;
switch (choose){
case 1:
cout << "请输入二叉树中的元素,空的左右孩子以#替代:" << endl;
binary_tree.create_preorder(root);
break;
case 2:
cout << "先序遍历:" << endl;
binary_tree.preorder_recursive(root);
cout << endl << "中序遍历:" << endl;
binary_tree.inorder_recursive(root);
cout << endl << "后序遍历:" << endl;
binary_tree.postorder_recursive(root);
cout << endl;
break;
case 3:
cout << "先序遍历:" << endl;
cout << "方法一:";
binary_tree.preorder_no_recursive(root);
cout << endl << "方法二:";
binary_tree.preorder_no_recursive2(root);
cout << endl << "中序遍历:" << endl;
binary_tree.inorder_no_recursive(root);
cout << endl << "后序遍历:" << endl;
binary_tree.postorder_no_recursive(root);
cout << endl;
break;
case 4:
cout << "层次遍历:" << endl;
binary_tree.levelorder(root);
cout << endl;
break;
case 5:
depth = 1;
level = 1;
binary_tree.tree_depth(root, depth, level);
cout << "二叉树的高度为:" << depth << endl;
break;
case 6:
cout << "二叉树的叶子个数为:" << binary_tree.leaf_count(root) << endl;
break;
case 7:
cout << "二叉树的节点个数为:" << binary_tree.node_count(root) << endl;
break;
case 0:
flag = false;
break;
default:
cout << "输入错误,请重新输入" << endl;
}
}
return 0;
}
参考:
http://blog.youkuaiyun.com/hackbuteer1/article/details/6583988
http://www.cnblogs.com/dolphin0520/archive/2011/08/25/2153720.html