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)); } #endifmain.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.csdn.net/hackbuteer1/article/details/6583988
http://www.cnblogs.com/dolphin0520/archive/2011/08/25/2153720.html