树类的定义和遍历
来源:互联网 发布:东方财富网 数据 编辑:程序博客网 时间:2024/06/05 22:57
实现树类的定义,结点的增删,以及先根,后根,层序周游遍历
#include <iostream>#include <queue>using namespace std;template <class T> class Tree; //声明树类template <class T>class TreeNode {friend class Tree<T>;private: T m_Value; //树结点的值 TreeNode<T>* pChild; //左子结点 TreeNode<T>* pSibling; //右兄弟结点public: TreeNode(const T& value); //拷贝构造函数 virtual ~TreeNode() {}; //析构函数 bool isLeaf(); //如果结点是叶,返回true T Value(); //返回结点的值 TreeNode<T>* LeftMostChild(); //返回第一个左孩子 TreeNode<T>* RightSibling(); //返回右兄弟 void setValue(T&); //设置结点的值 void setChild(TreeNode<T>* pointer); //设置左孩子 void setSibling(TreeNode<T>* pointer); //设置右兄弟 void InsertFirst(TreeNode<T>* node); //以第一个左孩子身份插入结点 void InsertNext(TreeNode<T>* node); //以右兄弟的身份插入结点};template<class T>TreeNode<T>::TreeNode(const T& value) { //拷贝构造函数 m_Value=value; pChild=NULL; pSibling=NULL;}template <class T>bool TreeNode<T>::isLeaf() { //如果结点是叶,返回true if (pChild == NULL) return true; return false;}template<class T>T TreeNode<T>::Value() { //返回结点的值 return m_Value;}template<class T>TreeNode<T>* TreeNode<T>::LeftMostChild() { //返回第一个左孩子 return pChild;}template<class T>TreeNode<T>* TreeNode<T>::RightSibling() { //返回右兄弟 return pSibling;}template <class T>void TreeNode<T>::setValue(T& value) { //设置结点的值 m_Value = value;}template<class T>void TreeNode<T>::setChild(TreeNode<T>* pointer) { //设置左孩子 pChild=pointer;}template<class T>void TreeNode<T>::setSibling(TreeNode<T>* pointer) { //设置右兄弟 pSibling=pointer;}template <class T>void TreeNode<T>::InsertFirst(TreeNode<T>* node) { //以第一个孩子的身份插入结点 if (pChild) node->pSibling = pChild; pChild = node;}template<class T>void TreeNode<T>::InsertNext(TreeNode<T>* node) { //以右兄弟的身份插入结点 if(pSibling) node->pSibling=pSibling; pSibling=node;}template <class T>class Tree {private: TreeNode<T>* root; //树根结点 void DestroyNodes(TreeNode<T>*root); //删除以root为根的子树public: Tree(); //构造函数 virtual ~Tree(); //析构函数 TreeNode<T>* getRoot(); //返回树中的根结点 void CreateRoot(const T& rootValue); //创建树中的根结点,使根结点元素的值为rootValue bool isEmpty(); //判断是否为空树,如果是则返回true TreeNode<T>* Parent(TreeNode<T>* current); //返回current结点的父结点 TreeNode<T>* PrevSibling(TreeNode<T>* current); //返回current结点的前一个邻居结点 void DeleteSubTree(TreeNode<T>* subroot); //删除以subroot为根的子树的所有结点 void RootFirstTraverse(TreeNode<T>* root); //先根深度优先周游树 void RootLastTraverse(TreeNode<T>* root); //后根深度优先周游树 void WidthTraverse(TreeNode<T>* root); //广度优先周游树 void Visit(T Value) { //访问 cout << Value; };};template <class T>Tree<T>::Tree() { //构造函数 root=NULL;}template <class T>Tree<T>::~Tree() { //析构函数 while(root) DeleteSubTree(root);}template <class T>TreeNode<T>* Tree<T>::getRoot() { //返回树中的根结点 return root;}template <class T>void Tree<T>::CreateRoot(const T& rootValue) {//创建树中的根结点,使根结点元素的值为rootValue if(!root) root=new TreeNode<T>(rootValue);}template <class T>bool Tree<T>::isEmpty() { //判断是否为空树,如果是则返回true if(root) return false; return true;}template <class T>TreeNode<T>* Tree<T>::PrevSibling(TreeNode<T>* current) {//返回current结点的前一个邻居结点 using std::queue; //使用STL队列 queue<TreeNode<T>*> aQueue; TreeNode<T>* pointer=root; //标识当前结点 TreeNode<T>* prev=NULL; //标识当前结点的前一个兄弟结点 //当前结点为空,树为空或所求结点为根结点时,返回NULL if((current==NULL)||(pointer==NULL)||(current==root)) return NULL; while(pointer) { if(pointer==current) return prev; //找到当前结点 aQueue.push(pointer); prev=pointer; pointer=pointer->pSibling; //沿当前结点右兄弟结点链寻找 } while(!aQueue.empty()) { prev=NULL; pointer=aQueue.front(); aQueue.pop(); //出队列 pointer=pointer->LeftMostChild(); //下降到左子结点 while(pointer) { if(pointer==current) return prev; aQueue.push(pointer); prev=pointer; pointer=pointer->pSibling; //沿当前结点右兄弟结点链寻找 }//end while }//end while return NULL;}template <class T>TreeNode<T>* Tree<T>::Parent(TreeNode<T>* current) { using std::queue; // 使用STL队列 queue<TreeNode<T>*> aQueue; TreeNode<T>* pointer = root; TreeNode<T>* upperlevelpointer = NULL; // 用于记录parent结点 if (current != NULL && pointer != current) { while (pointer) { // 森林中所有根结点进队列 if (current == pointer) return NULL; // 根的父结点指针为空,返回 aQueue.push(pointer); pointer=pointer-> RightSibling(); } while (!aQueue.empty()) { pointer = aQueue.front(); // 取队列首结点指针 aQueue.pop(); // 出队列 upperlevelpointer = pointer; // 指向上一层的结点 pointer = pointer-> LeftMostChild(); // 指向当前结点的最左孩子 while (pointer) { // 当前结点的子结点进队列 if (current == pointer) return upperlevelpointer; // 返回父结点指针 else { aQueue.push(pointer); pointer = pointer->RightSibling(); } }//end while }//end while }//end if return NULL;}template <class T>void Tree<T>::DestroyNodes(TreeNode<T>* root) { //删除以root为根的子树的所有结点 if (root) { DestroyNodes(root->LeftMostChild()); //递归删除第一子树 DestroyNodes(root->RightSibling()); //递归删除其他子树 delete root; //删除根结点 }}template <class T>void Tree<T>::DeleteSubTree(TreeNode<T>* subroot) { // 删除以subroot为根的子树的所有结点 if (subroot == NULL) return; TreeNode<T>* pointer = Parent (subroot); // 找subroot的父结点 if (pointer == NULL) // subroot就是森林第一个树根 root = subroot->RightSibling(); else if (pointer-> LeftMostChild() == subroot) // subroot为最左子结点的情况 pointer->setChild(subroot->RightSibling()); else { // subroot有左兄弟 pointer = pointer-> LeftMostChild(); // 下降到最左兄弟 while (pointer-> RightSibling() != subroot) // 顺右链找到直接左兄弟 pointer = pointer ->RightSibling(); pointer->setSibling(subroot->RightSibling()); } subroot->setSibling(NULL); DestroyNodes(subroot);}//树的深度、广度周游算法template <class T>void Tree<T>::RootFirstTraverse(TreeNode<T>* root) { //先根深度优先周游树 while (NULL != root) { Visit(root->Value()); //访问当前结点 RootFirstTraverse(root->LeftMostChild()); //周游头一棵树树根的子树 root = root->RightSibling(); //周游其他的树 }}template <class T>void Tree<T>::RootLastTraverse(TreeNode<T>* root) { //后根深度优先周游树 while (NULL != root) { RootLastTraverse(root->LeftMostChild()); //周游头一棵树树根的子树 Visit(root->Value()); //访问当前结点 root = root->RightSibling(); //周游其他的树 }}template <class T>void Tree<T>::WidthTraverse(TreeNode<T>* root) { // 广度优先周游树 using std::queue; // 使用STL队列 queue<TreeNode<T>*> aQueue; TreeNode<T>* pointer = root; // 根作为当前结点 while (pointer) { aQueue.push(pointer); // 当前结点进入队列 pointer = pointer->RightSibling(); // 指向当前结点的右兄弟 }//end while while (!aQueue.empty()) { pointer = aQueue.front(); // 取队列首结点指针 aQueue.pop(); // 出队列 Visit(pointer->Value()); // 访问当前结点 pointer = pointer-> LeftMostChild(); // 指向当前结点的最左孩子 while (pointer) { // 当前结点的子结点进队列 aQueue.push(pointer); pointer = pointer->RightSibling(); } }//end while}// 函数功能:周游树,在这里只列举一种(先根次序)void Traverse(Tree<char> *tree){ cout << "FirstRoot traverse: "; tree->RootFirstTraverse(tree->getRoot()); // 先根深度优先周游 cout << endl; cout << "LastRoot traverse: "; tree->RootLastTraverse(tree->getRoot()); // 后根深度 cout << endl; cout << "Width traverse : "; tree->WidthTraverse(tree->getRoot()); // 广度遍历 cout << endl << endl;}int main(){ //建树 Tree<char> aTree; aTree.CreateRoot('A'); TreeNode<char> *f = new TreeNode<char>('F'); TreeNode<char> *e = new TreeNode<char>('E'); TreeNode<char> *d = new TreeNode<char>('D'); TreeNode<char> *c = new TreeNode<char>('C'); TreeNode<char> *b = new TreeNode<char>('B'); e->setSibling(f); c->setSibling(d); c->setChild(e); b->setSibling(c); aTree.getRoot()->setChild(b); TreeNode<char> *x = new TreeNode<char>('X'); TreeNode<char> *y = new TreeNode<char>('Y'); TreeNode<char> *z = new TreeNode<char>('Z'); aTree.getRoot()->setSibling(x); x->setChild(y); y->setSibling(z); //显示树的结构 cout << " A X \n"; cout << " / | \\ / \\ \n"; cout << " B C D Y Z \n"; cout << " / \\ \n"; cout << " E F \n"; cout << "\n"; //判断树是否为空 aTree.isEmpty(); //周游树 cout << "周游树:\n"; Traverse(&aTree); // 结果,先根:ABCEFDXYZ,后根:BEFCDAYZX,层序:AXBCDYZEF //e结点插入第一个孩子G cout << "e结点插入第一个孩子G的结果:\n"; TreeNode<char> *g = new TreeNode<char>('G'); e->InsertFirst(g); //周游树 Traverse(&aTree); // 结果,先根:ABCEGFDXYZ,后根:BGEFCDAYZX,层序:AXBCDYZEFG //e结点以第一个兄弟的身份插入H cout << "e结点以第一个兄弟的身份插入H的结果:\n"; TreeNode<char> *h = new TreeNode<char>('H'); e->InsertNext(h); //周游树 Traverse(&aTree); // 结果,先根:ABCEGHFDXYZ,后根:BGEHFCDAYZX,层序:AXBCDYZEHFG //获得C的父结点 cout << "获得C的父结点: "; aTree.Visit(aTree.Parent(c)->Value()); cout << endl; //获得H的上一个兄弟结点 cout << "获得H的上一个兄弟结点: "; aTree.Visit(aTree.PrevSibling(h)->Value()); cout << endl;// aTree.Visit(aTree.PrevSibling(e)->Value());// cout << endl; //求父结点 cout<<"E的父结点:"; aTree.Visit(aTree.Parent(e)->Value()); cout<<endl; cout<<"D的父结点:"; aTree.Visit(aTree.Parent(d)->Value()); cout<<endl; cout<<"F的父结点:"; aTree.Visit(aTree.Parent(f)->Value()); cout<<endl; cout<<"Z的父结点:"; aTree.Visit(aTree.Parent(z)->Value()); cout<<endl; cout<<"X的父结点:"; if (aTree.Parent(x) == NULL) cout<< "Parent is NULL!" << endl; //删除根为E的子树 cout << "删除E子树:" << endl; aTree.DeleteSubTree(e); Traverse(&aTree); //删除根为C的子树 cout << "删除C子树:" << endl; aTree.DeleteSubTree(c); Traverse(&aTree); // 结果,先根:ABDXYZ,后根:BDAYZX,层序:AXBDYZ return 0;}
0 0
- 树类的定义和遍历
- 二叉树的基本定义和遍历
- 二叉树的定义-创建-遍历三步走
- 二叉树的定义与遍历
- 二叉树的定义、前序遍历、广度遍历
- 二叉搜索树 ( 二叉查找树)( 二叉排序树)的定义和遍历
- linux shell 中数组的定义和for循环遍历
- 【数据结构】二叉树的定义,递归遍历,非递归遍历,层次遍历,深度等
- 类的定义和对象的定义
- 二叉树的遍历(层遍历和深度遍历)
- 数据结构 各种树的定义及遍历方法
- 树结构的定义,几种遍历方法
- 实验五 二叉树的定义与遍历
- 字符数组和字符串,char 和string定义的字符串的区别与遍历
- 字符数组和字符串,char 和string定义的字符串的区别与遍历
- 字符数组和字符串,char 和string定义的字符串的区别与遍历
- Kotlin入门篇(五),Loop和Range,Kotlin中区间的定义和遍历
- 树的建立和遍历
- BZOJ 2875 [Noi2012] 随机数生成器 题解与分析
- SHTSC记 13.12.14
- SQL查询数据库名、表名、列名
- 解决:无法检索“mvc4.Models.Movie”的元数据。The connection string in the application's configuration file does no
- JS实践与写博客-序
- 树类的定义和遍历
- asp获取当前页面url
- hive partition简介
- Introduction to JavaScipt
- asp语言中if判断语句的求助
- 黑苹果硬件支持列表【最新】2013.12
- 算法之旅,直奔<algorithm>之八 copy_n
- MyEclipse 快捷键
- MyEclipse 创建maven webProject