二叉树C++实现
2012-09-06 18:06
155 查看
最近整理原来的一些代码,脑子有点不好使,还是记下来吧。
//binary_tree.h,遍历包含了递归和非递归两种,层次遍历
//bianry_tree.cpp
//binary_tree.h,遍历包含了递归和非递归两种,层次遍历
#ifndef _BINARY_TREE_H_ #define _BINARY_TREE_H_ template<class T> struct BiNode { T data; BiNode<T>* lchild, *rchild; }; template<class T> class BiTree { public: BiTree(); ~BiTree(); BiNode<T>* GetRoot(); void PreOrder(BiNode<T>* node); void InOrder(BiNode<T>* node); void PostOrder(BiNode<T>* node); //非递归实现 void PreOrderNonRec(BiNode<T>* node); void InOrderNonRec(BiNode<T>* node); void PostOrderNonRec(BiNode<T>* node); void LevelOrder(BiNode<T>* node);//层次遍历 protected: private: BiNode<T>* m_root; BiNode<T>* Create(); void Release(BiNode<T>* root); }; #endif
//bianry_tree.cpp
#include <iostream> #include <stack> #include <queue> using namespace std; template<class T> BiNode<T>* BiTree<T>::GetRoot() { return m_root; } template<class T> BiTree<T>::BiTree() { m_root = new BiNode<T>; m_root = Create(); } template<class T> BiTree<T>::~BiTree() { Release(m_root); } template<class T> BiNode<T>* BiTree<T>::Create() { char ch; cin>>ch; BiNode<T>* pnode; if (ch == '#') pnode = NULL; else { pnode = new BiNode<T>; pnode->data = ch; pnode->lchild = Create(); pnode->rchild = Create(); } return pnode; } template<class T> void BiTree<T>::Release( BiNode<T>* root ) { if(root != NULL) { Release(root->lchild); Release(root->rchild); } } template<class T> void BiTree<T>::PreOrder(BiNode<T>* node) { //TLR的第一个一定是树根 if(node == NULL) return; else { cout<<node->data<<" "; PreOrder(node->lchild); PreOrder(node->rchild); } } template<class T> void BiTree<T>::InOrder(BiNode<T>* node) { //由前序遍历和中序遍历可以确定唯一二叉树 //后序遍历和中序遍历也可以 //但是前序和后序一起不可以 //特点是 前后定根,中序定左右 if(node == NULL) return; else { InOrder(node->lchild); cout<<node->data<<" "; InOrder(node->rchild); } } template<class T> void BiTree<T>::PostOrder(BiNode<T>* node) { //LRT的最后一个一定是树根 if(node == NULL) return; else { PostOrder(node->lchild); PostOrder(node->rchild); cout<<node->data<<" "; } } template<class T> void BiTree<T>::PreOrderNonRec(BiNode<T>* node) { stack<BiNode<T>*> s; BiNode<T>* p = node; while(p != NULL || !s.empty()) { while(p != NULL) { cout<<p->data<<" "; s.push(p); p = p->lchild; } if (!s.empty()) { p = s.top(); s.pop(); p = p->rchild; } } } template<class T> void BiTree<T>::InOrderNonRec(BiNode<T>* node) { //先序遍历非递归需要借助stack s来实现,模拟递归调用 //总的循环边界是当前节点不为空或者stack不空, //@1 在当前节点p非空时候,将p入栈s,p的左子树赋给p,保证左子树都能入栈 // p为空时候,也就是左子树最左边访问到了,这时候在栈非空的时候 //@2 取栈顶给p,输入p,出栈,这时候最底层的最左边节点访问了,将p的右子树赋给p,重复@1 stack<BiNode<T>*> s; BiNode<T>* p = node; while(p != NULL || !s.empty()) { while (p != NULL) { s.push(p); p = p->lchild; } if (!s.empty()) { p = s.top(); cout<<p->data<<" "; s.pop(); p = p->rchild; } } } template<class T> void BiTree<T>::PostOrderNonRec(BiNode<T>* node) { //要保证根结点在左孩子和右孩子访问之后才能访问, //因此对于任一结点P,先将其入栈。如果P不存在左孩子和右孩子,则可以直接访问它; //或者P存在左孩子或者右孩子,但是其左孩子和右孩子都已被访问过了,则同样可以直接访问该结点。 //若非上述两种情况,则将P的右孩子和左孩子依次入栈,这样就保证了每次取栈顶元素的时候, //左孩子在右孩子前面被访问,左孩子和右孩子都在根结点前面被访问。 if(node == NULL) return; stack<BiNode<T>*> s; s.push(node);//node是root BiNode<T>* pre = NULL; BiNode<T>* cur; while(!s.empty()) { cur = s.top(); if(cur->lchild == NULL && cur->rchild == NULL || (pre != NULL)&&(pre == cur->lchild || pre == cur->rchild) )//上一次访问的是当前节点的左子树 { cout<<cur->data<<" "; s.pop(); pre = cur; } else { if(cur->rchild) s.push(cur->rchild); if (cur->lchild) s.push(cur->lchild); } } } template<class T> void BiTree<T>::LevelOrder(BiNode<T>* node) { //层次遍历需要queue来实现,思路: //@1初始化queue // if root为空 返回 //@2 push(root) //@3 while(queue不为空) // s <-- queue.front() // queue.pop() // 输入s.data // if(s的左子树不空) // s的左子树入队 // if(s的右子树不空) // s的右子树入队 queue<BiNode<T>*> q; BiNode<T>* s = node; if(s == NULL) return; q.push(s); while(!q.empty()) { s= q.front(); q.pop(); cout<<s->data<<" "; if (s->lchild) q.push(s->lchild); if(s->rchild) q.push(s->rchild); } }【测试】
#include "list.h" #include "binary_tree.h" #include <iostream> using namespace std; int main() { BiTree<char> my_tree; my_tree.PreOrder(my_tree.GetRoot()); cout<<endl; my_tree.PreOrderNonRec(my_tree.GetRoot()); cout<<endl; my_tree.InOrder(my_tree.GetRoot()); cout<<endl; my_tree.InOrderNonRec(my_tree.GetRoot()); cout<<endl; my_tree.PostOrder(my_tree.GetRoot()); cout<<endl; my_tree.LevelOrder(my_tree.GetRoot()); cout<<endl; my_tree.PostOrderNonRec(my_tree.GetRoot()); cout<<endl; }
相关文章推荐
- 二叉树(c++实现)
- c++实现二叉树的先序遍历,中序遍历,后序遍历(递归方法)及运行实例结果
- C++二叉树的实现
- 二叉树的后序遍历非递归算法之C++实现 选择自 xuyongfeng 的 Blog
- 数据结构C++实现——二叉树
- 二叉树的C++简单实现
- 【数据结构】二叉树的构建及其遍历(C++实现)
- c++实现二叉树(递归)
- C++实现二叉树,运用模板,界面友好,操作方便 运行流畅
- C++ 二叉树的构建,先序/中序/后序的递归/非递归实现
- c++实现二叉树的插入、删除、查询、遍历和树形打印
- 简单链式二叉树(C++模版技术实现)
- 二叉树的基本操作以及相关问题的求解—C++实现
- c++模板实现二叉树,线索化,线索化遍历,非递归遍历及一些基本操作
- 二叉树的非递归前序、中序以及后序遍历C++模版类实现
- 二叉树的深度优先遍历与广度优先遍历 [ C++ 实现 ]
- c/c++实现利用二叉树的先序遍历和中序遍历序列重建树
- 树和二叉树的存储结构的实现(C/C++实现)
- c++实现二叉树的先序遍历,中序遍历,后序遍历(递归方法)及运行实例结果
- 二叉树的C++模板类头文件源代码实现