当前位置:   article > 正文

二叉树——从建立到销毁_二叉树的销毁

二叉树的销毁

目录

结构体和类定义

一、二叉树建立

前序遍历建立二叉树

二、遍历

2.1前序遍历

2.2中序遍历

2.3后序遍历

2.4层次遍历

三、求结点

3.1求父结点

3.2求左子结点、右子结点

四、求高度、深度、判空等

4.1高度

4.2结点个数

4.3判空

4.4结点是否存在

4.5结点数据

4.6销毁二叉树

五、主函数

六、总代码

七、总结


前言

个人认为二叉树的核心是递归,绝大部分的操作,都可以使用递归来实现。

主要操作

结构体和类定义

  1. template <class T>
  2. struct BinTreeNode{
  3. T data;
  4. BinTreeNode *leftChild,*rightChild;
  5. BinTreeNode():leftChild(NULL),rightChild(NULL){}
  6. BinTreeNode(T x,BinTreeNode<T> *l=NULL,BinTreeNode<T> *r=NULL)
  7. :data(x),leftChild(l),rightChild(r){}
  8. };
  9. //类定义
  10. //对象: 结点的有限集合, 二叉树是有序树
  11. template <class T>
  12. class BinaryTree {
  13. public:
  14. //构造函数
  15. BinaryTree ():root(NULL){}
  16. BinaryTree(T value):RefValue(value),root(NULL){}
  17. BinaryTree(BinaryTree<T>& s);
  18. ~BinaryTree(){destroy(root);}
  19. BinaryTree (BinTreeNode<T> *lch,BinTreeNode<T> *rch, T item);
  20. //构造函数, 以item为根, lch和rch为左、右子
  21. //树构造一棵二叉树
  22. //BinTreeNode<T> *createpretree(int l,int i,string &a);
  23. void CreatTree(BinTreeNode<T> *& root);
  24. //高度、深度、判空、取结点
  25. int Height (BinTreeNode<T> * root);//求树深度或高度{return Height(root);}
  26. int Size (BinTreeNode<T> * root);//求树中结点个数{return Size(root);}
  27. bool IsEmpty (){return (root==NULL)?true:false;}; //判二叉树空否?
  28. bool Find (T& item,BinTreeNode<T> * root); //判断item是否在树中
  29. BinTreeNode<T> *getData(T& item,BinTreeNode<T> * root); //取得结点数据
  30. //求结点
  31. BinTreeNode<T> *Parent (BinTreeNode <T> *subTree,BinTreeNode<T> *t);
  32. //求结点 t 的双亲{return (root==NULL||root==t)?NULL:Parent(root,t);}
  33. BinTreeNode<T> *LeftChild (BinTreeNode<T> *t)//求结点 t 的左子女
  34. {return (t!=NULL)?t->leftChild:NULL;}
  35. BinTreeNode<T> *RightChild (BinTreeNode<T> *t)//求结点 t 的右子女
  36. {return (t!=NULL)?t->rightChild:NULL;}
  37. //遍历
  38. BinTreeNode<T> *getRoot (){return root;} //取根
  39. BinTreeNode<T> *CopyTree( BinTreeNode<T> *orignode);
  40. void preOrder ( BinTreeNode<T> *root);//前序遍历
  41. void inOrder ( BinTreeNode<T> * root);//中序遍历
  42. void postOrder ( BinTreeNode<T> * root);//后序遍历
  43. void levelOrder (BinTreeNode<T> * root);//层次序遍历
  44. protected:
  45. BinTreeNode<T> * root;
  46. T RefValue;
  47. void destroy (BinTreeNode<T> * subTree);
  48. };

一、二叉树建立

前序遍历建立二叉树

空传入

  1. template <class T>
  2. void BinaryTree<T>::CreatTree(BinTreeNode<T> *& root)
  3. { T item;
  4. cin>>item;
  5. if(item!=RefValue)
  6. { root=new BinTreeNode<T>(item);
  7. if(root ==NULL)
  8. { cerr<<"分配结点失败!\n"; exit(1); }
  9. CreatTree(root->leftChild);
  10. CreatTree(root->rightChild);
  11. }
  12. else root=NULL;
  13. }

传引用

  1. template <class T>
  2. BinTreeNode<T> * BinaryTree<T>::createpretree(int l,int i,string &a)
  3. {//l为数组a的长度,i为数组下标
  4. BinTreeNode<T> *root;
  5. if(l==0||a[i]=='#'||i==l)root=NULL;
  6. else
  7. {
  8. root=new BinTreeNode<T>(a[i++]);
  9. root->leftChild=createpretree(l,i,a);
  10. root->rightChild=createpretree(l,++i,a);
  11. }
  12. return root;
  13. }

二、遍历

2.1前序遍历

  1. template <class T>
  2. void BinaryTree<T>::preOrder(BinTreeNode<T> * root)
  3. {
  4. if (root != NULL)
  5. {
  6. cout<<root->data<<" "; //先序访问根结点
  7. preOrder(root->leftChild); //遍历左子树
  8. preOrder(root->rightChild); //先序遍历右子树
  9. }
  10. }

2.2中序遍历

  1. template <class T>
  2. void BinaryTree<T>::inOrder(BinTreeNode<T> * root)
  3. {
  4. if (root != NULL)
  5. {
  6. inOrder(root->leftChild); //中序遍历左子树
  7. cout<<root->data<<" "; //访问根结点
  8. inOrder(root->rightChild); //中序遍历右子树
  9. }
  10. }

2.3后序遍历

  1. template <class T>
  2. void BinaryTree<T>::postOrder(BinTreeNode<T> * root)
  3. {
  4. if (root != NULL)
  5. {
  6. postOrder(root->leftChild); //后序遍历左子树
  7. postOrder(root->rightChild); //遍历右子树
  8. cout<<root->data<<" "; //后序访问根结点
  9. }
  10. }

2.4层次遍历

  1. template <class T>
  2. void BinaryTree<T>::levelOrder(BinTreeNode<T> *root)
  3. { if (root == NULL) return;
  4. queue<BinTreeNode<T> * > Q;
  5. BinTreeNode<T> *p;
  6. Q.push(root); //根结点入队列
  7. while (!Q.empty())
  8. {
  9. p=Q.front();
  10. cout<<(Q.front())->data<<" "; //输出出队结点的数据
  11. Q.pop(); //队头结点出队
  12. if (p->leftChild != NULL) //若出队结点有左孩子
  13. { Q.push(p->leftChild);} //左孩子入队列p=p->leftChild;
  14. if (p->rightChild != NULL)
  15. {Q.push(p->rightChild);
  16. }
  17. }
  18. }

有一种方法是使用自定义的队列,思路大致和上面相同,但在此不写怎么麻烦的方法了。

三、求结点

3.1求父结点

  1. template <class T>
  2. BinTreeNode<T> *BinaryTree<T>::
  3. Parent (BinTreeNode <T> *subTree,BinTreeNode <T> *t)
  4. {
  5. if (subTree == NULL) return NULL;
  6. if (subTree->leftChild == t ||subTree->rightChild == t)
  7. return subTree; //找到, 返回父结点地址
  8. BinTreeNode <T> *p;
  9. if ((p = Parent (subTree->leftChild, t)) != NULL)
  10. return p; //递归在左子树中搜索
  11. else return Parent (subTree->rightChild, t);
  12. //递归在右子树中搜索
  13. }

3.2求左子结点、右子结点

  1. //定义在类中
  2. BinTreeNode<T> *LeftChild (BinTreeNode<T> *t)
  3. {return (t!=NULL)?t->leftChild:NULL;}//求结点 t 的左子女
  4. BinTreeNode<T> *RightChild (BinTreeNode<T> *t)
  5. {return (t!=NULL)?t->rightChild:NULL;} //求结点 t 的右子女

四、求高度、深度、判空等

4.1高度

  1. template <class T>
  2. int BinaryTree<T>::Height(BinTreeNode<T> * root)
  3. {
  4. if (root == NULL) return 0;
  5. else
  6. {
  7. int i = Height(root->leftChild);
  8. int j = Height(root->rightChild);
  9. return (i < j) ? j+1 : i+1;
  10. }
  11. }

4.2结点个数

  1. template <class T>
  2. int BinaryTree<T>::Size(BinTreeNode<T> * root)
  3. {
  4. if (root == NULL) return 0; //空树
  5. else
  6. return 1+Size(root->leftChild)+Size(root->rightChild);
  7. }

4.3判空

  1. //在类中
  2. bool IsEmpty (){return (root==NULL)?true:false;};

4.4结点是否存在

  1. template<class T>
  2. bool BinaryTree<T>::Find (T& item,BinTreeNode<T> * root)
  3. {
  4. if(this->getData(item,root)==NULL)return false;
  5. else return true;
  6. }

4.5结点数据

  1. template<class T>
  2. BinTreeNode<T> *BinaryTree<T>::getData(T& item,BinTreeNode<T> * root)
  3. {
  4. if(root==NULL)return NULL;
  5. if(root->data==item)return root;
  6. return getData(item,root->leftChild)!=NULL?getData(item,root->leftChild):getData(item,root->rightChild);
  7. }

4.6销毁二叉树

  1. template<class T>
  2. void BinaryTree<T>::destroy (BinTreeNode<T>* subTree) {
  3. //私有函数: 后序遍历删除根为subTree的子树;
  4. if (subTree != NULL) {
  5. destroy (subTree->leftChild); //删除左子树
  6. destroy (subTree->rightChild); //删除右子树
  7. delete subTree; //删除根结点
  8. }
  9. }

五、主函数

  1. int main()
  2. {
  3. char ch;
  4. cout<<"输入结束标志:";
  5. cin>>ch;
  6. BinaryTree<char> t(ch);
  7. BinTreeNode<char>* head=t.getRoot();
  8. t.CreatTree(head);
  9. return 0;
  10. }

六、总代码

  1. #include<bits/stdc++.h>
  2. using namespace std;
  3. template <class T>
  4. struct BinTreeNode{
  5. T data;
  6. BinTreeNode *leftChild,*rightChild;
  7. BinTreeNode():leftChild(NULL),rightChild(NULL){}
  8. BinTreeNode(T x,BinTreeNode<T> *l=NULL,BinTreeNode<T> *r=NULL)
  9. :data(x),leftChild(l),rightChild(r){}
  10. };
  11. //类定义
  12. //对象: 结点的有限集合, 二叉树是有序树
  13. template <class T>
  14. class BinaryTree {
  15. public:
  16. BinaryTree ():root(NULL){} //构造函数
  17. BinaryTree(T value):RefValue(value),root(NULL){}
  18. BinaryTree(BinaryTree<T>& s);
  19. ~BinaryTree(){destroy(root);}
  20. BinaryTree (BinTreeNode<T> *lch,BinTreeNode<T> *rch, T item);
  21. //构造函数, 以item为根, lch和rch为左、右子
  22. //树构造一棵二叉树
  23. //BinTreeNode<T> *createpretree(int l,int i,string &a);
  24. void CreatTree(BinTreeNode<T> *& root);
  25. int Height (BinTreeNode<T> * root);//求树深度或高度{return Height(root);}
  26. int Size (BinTreeNode<T> * root);//求树中结点个数{return Size(root);}
  27. bool IsEmpty (){return (root==NULL)?true:false;}; //判二叉树空否?
  28. BinTreeNode<T> *Parent (BinTreeNode <T> *subTree,BinTreeNode<T> *t);
  29. //求结点 t 的双亲{return (root==NULL||root==t)?NULL:Parent(root,t);}
  30. BinTreeNode<T> *LeftChild (BinTreeNode<T> *t)
  31. {return (t!=NULL)?t->leftChild:NULL;}//求结点 t 的左子女
  32. BinTreeNode<T> *RightChild (BinTreeNode<T> *t)
  33. {return (t!=NULL)?t->rightChild:NULL;} //求结点 t 的右子女
  34. //bool Insert (const T& item); //在树中插入新元素
  35. //bool Remove (T item); //在树中删除元素
  36. bool Find (T& item,BinTreeNode<T> * root); //判断item是否在树中
  37. BinTreeNode<T> *getData(T& item,BinTreeNode<T> * root); //取得结点数据
  38. BinTreeNode<T> *getRoot (){return root;} //取根
  39. BinTreeNode<T> *CopyTree( BinTreeNode<T> *orignode);
  40. void preOrder ( BinTreeNode<T> *root);//前序遍历
  41. void inOrder ( BinTreeNode<T> * root);//中序遍历
  42. void postOrder ( BinTreeNode<T> * root);//后序遍历
  43. void levelOrder (BinTreeNode<T> * root);//层次序遍历
  44. protected:
  45. BinTreeNode<T> * root;
  46. T RefValue;
  47. void destroy (BinTreeNode<T> * subTree);
  48. };
  49. //template <class T>
  50. //BinaryTree::BinaryTree()
  51. /*
  52. //建立二叉树
  53. template <class T>
  54. BinTreeNode<T> * BinaryTree<T>::createpretree(int l,int i,string &a)
  55. {
  56. BinTreeNode<T> *root;
  57. if(l==0||a[i]=='#'||i==l)root=NULL;
  58. else
  59. {
  60. root=new BinTreeNode<T>(a[i++]);
  61. root->leftChild=createpretree(l,i,a);
  62. root->rightChild=createpretree(l,++i,a);
  63. }
  64. return root;
  65. }*/
  66. //先序遍历创建一棵二叉树
  67. template <class T>
  68. void BinaryTree<T>::CreatTree(BinTreeNode<T> *& root)
  69. { T item;
  70. cin>>item;
  71. if(item!=RefValue)
  72. { root=new BinTreeNode<T>(item);
  73. if(root ==NULL)
  74. { cerr<<"分配结点失败!\n"; exit(1); }
  75. CreatTree(root->leftChild);
  76. CreatTree(root->rightChild);
  77. }
  78. else root=NULL;
  79. }
  80. //遍历
  81. //先序遍历
  82. template <class T>
  83. void BinaryTree<T>::preOrder(BinTreeNode<T> * root)
  84. {
  85. if (root != NULL)
  86. { cout<<root->data<<" "; //先序访问根结点
  87. preOrder(root->leftChild); //遍历左子树
  88. preOrder(root->rightChild); //先序遍历右子树
  89. }
  90. }
  91. //中序遍历
  92. template <class T>
  93. void BinaryTree<T>::inOrder(BinTreeNode<T> * root)
  94. {
  95. if (root != NULL)
  96. {
  97. inOrder(root->leftChild); //中序遍历左子树
  98. cout<<root->data<<" "; //访问根结点
  99. inOrder(root->rightChild); //中序遍历右子树
  100. }
  101. }
  102. //后序遍历
  103. template <class T>
  104. void BinaryTree<T>::postOrder(BinTreeNode<T> * root)
  105. {
  106. if (root != NULL)
  107. {
  108. postOrder(root->leftChild); //后序遍历左子树
  109. postOrder(root->rightChild); //遍历右子树
  110. cout<<root->data<<" "; //后序访问根结点
  111. }
  112. }
  113. //层次遍历
  114. template <class T>
  115. void BinaryTree<T>::levelOrder(BinTreeNode<T> *root)
  116. { if (root == NULL) return;
  117. queue<BinTreeNode<T> * > Q;
  118. BinTreeNode<T> *p;
  119. Q.push(root); //根结点入队列
  120. while (!Q.empty())
  121. {
  122. p=Q.front();
  123. cout<<(Q.front())->data<<" "; //输出出队结点的数据
  124. Q.pop(); //队头结点出队
  125. if (p->leftChild != NULL) //若出队结点有左孩子
  126. { Q.push(p->leftChild);} //左孩子入队列p=p->leftChild;
  127. if (p->rightChild != NULL)
  128. {Q.push(p->rightChild);
  129. }
  130. }
  131. }
  132. //结点个数
  133. template <class T>
  134. int BinaryTree<T>::Size(BinTreeNode<T> * root)
  135. {
  136. if (root == NULL) return 0; //空树
  137. else
  138. return 1+Size(root->leftChild)+Size(root->rightChild);
  139. }
  140. //空树高度为0
  141. template <class T>
  142. int BinaryTree<T>::Height(BinTreeNode<T> * root)
  143. {
  144. if (root == NULL) return 0;
  145. else
  146. {
  147. int i = Height(root->leftChild);
  148. int j = Height(root->rightChild);
  149. return (i < j) ? j+1 : i+1;
  150. }
  151. }
  152. //二叉树复制
  153. template <class T>
  154. BinTreeNode<T> * BinaryTree<T>::CopyTree( BinTreeNode<T> *orignode)
  155. {
  156. if(orignode==NULL) return NULL;
  157. BinTreeNode<T> *temp=new BinTreeNode<T>;
  158. temp->data=orignode->data;
  159. temp->leftChild=CopyTree(orignode->leftChild);
  160. temp->rightChild=CopyTree(orignode->rightChild);
  161. return temp;
  162. }
  163. //寻找双亲结点
  164. template <class T>
  165. BinTreeNode<T> *BinaryTree<T>::
  166. Parent (BinTreeNode <T> *subTree,BinTreeNode <T> *t)
  167. {
  168. if (subTree == NULL) return NULL;
  169. if (subTree->leftChild == t ||subTree->rightChild == t)
  170. return subTree; //找到, 返回父结点地址
  171. BinTreeNode <T> *p;
  172. if ((p = Parent (subTree->leftChild, t)) != NULL)
  173. return p; //递归在左子树中搜索
  174. else return Parent (subTree->rightChild, t);
  175. //递归在右子树中搜索
  176. }
  177. //查找结点数据
  178. template<class T>
  179. BinTreeNode<T> *BinaryTree<T>::getData(T& item,BinTreeNode<T> * root)
  180. {
  181. if(root==NULL)return NULL;
  182. if(root->data==item)return root;
  183. return getData(item,root->leftChild)!=NULL?getData(item,root->leftChild):getData(item,root->rightChild);
  184. }
  185. //查找结点是否在树中
  186. template<class T>
  187. bool BinaryTree<T>::Find (T& item,BinTreeNode<T> * root)
  188. {
  189. if(this->getData(item,root)==NULL)return false;
  190. else return true;
  191. }
  192. //销毁二叉树
  193. template<class T>
  194. void BinaryTree<T>::destroy (BinTreeNode<T>* subTree) {
  195. //私有函数: 后序遍历删除根为subTree的子树;
  196. if (subTree != NULL) {
  197. destroy (subTree->leftChild); //删除左子树
  198. destroy (subTree->rightChild); //删除右子树
  199. delete subTree; //删除根结点
  200. }
  201. }
  202. //BinTreeNode<char> *root;
  203. int main()
  204. {
  205. char ch;
  206. cout<<"输入结束标志:";
  207. cin>>ch;
  208. BinaryTree<char> t(ch);
  209. // cout<<"输入遍历序列:";
  210. // string a;
  211. // cin>>a;
  212. // int l=a.length();
  213. // int i=0;
  214. BinTreeNode<char>* head=t.getRoot();
  215. t.CreatTree(head);
  216. return 0;
  217. }

七、总结

点个赞再走吧~~

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/笔触狂放9/article/detail/622025
推荐阅读
相关标签
  

闽ICP备14008679号