当前位置:   article > 正文

实验三 二叉树的物理实现(左子右兄弟-顺序表)_左子右兄弟表示法

左子右兄弟表示法
  • 说明
  • 基于顺序表的左子/右兄弟结点表示法
  • 参考资料

一、说明

1、树的存储结构一般有父结点表示法(双亲表示法,一般是顺序表),子结点表示法(链表+顺序表),左子/右兄弟结点表示法(链表+顺序表)

2、在计算机科学中,二叉树每个结点最多有两个子树的树结构。通常子树被称作“左子树”(left subtree)和“右子树”(right subtree)(来源于百度百科);

3、左子结点/右兄弟结点表示法本质上是用二叉树来替换树,使用这种方法能把任意树替换为二叉树。如下图:

4、结点M的深度就是从根结点到M的路径长度。数的高度是等于最深结点的深度加1.任何深度为d的结点的层数都为d。根结点的层数为0,深度也为0(深度从0开始计数);

5、因为BIT一般为树状数组(Binary Indexed Tree)的简写,因此将二叉树(Binary Tree)相关命名为BinNode、BinTree等;

6、左儿子右兄弟结点表示法的中序遍历经查阅部分资料尚未找到正确方法,若有大牛知晓烦请告知;

7、调用遍历函数前,需要预处理,详见代码;

8、以下代码仅供参考。

 

二、基于顺序表的左子/右兄弟结点表示法

1、BinNode.h

  1. #include<iostream>
  2. using namespace std;
  3. #ifndef _BinNode
  4. #define _BinNode
  5. namespace wangzhe
  6. {
  7. template<typename E>
  8. class BinNode
  9. {
  10. private:
  11. E it;//数据域
  12. int l;//最左儿子结点下标
  13. int r;//右邻兄弟结点下标
  14. public:
  15. BinNode()
  16. {
  17. l=r=-1;
  18. }
  19. E& element()
  20. {
  21. return it;
  22. }
  23. void setElement(const E& e)
  24. {
  25. it=e;
  26. }
  27. int left() const
  28. {
  29. return l;
  30. }
  31. void setLeft(int b)
  32. {
  33. l=b;
  34. }
  35. int right() const
  36. {
  37. return r;
  38. }
  39. void setRight(int b)
  40. {
  41. r=b;
  42. }
  43. bool isLeaf()
  44. {
  45. return r==-1;
  46. }
  47. };
  48. }
  49. #endif

2、BinTree.h

  1. #include<iostream>
  2. using namespace std;
  3. #include"BinNode.h"
  4. #ifndef _BinTree
  5. #define _BinTree
  6. namespace wangzhe
  7. {
  8. template<typename E>
  9. class BinTree
  10. {
  11. private:
  12. int size;//能存储最大的结点个数
  13. BinNode<E>* T;//存储树结点的数组
  14. int *D;//存储各结点的深度
  15. int height;//树的高度
  16. public:
  17. BinTree(int sz);//构造函数
  18. ~BinTree();//析构函数
  19. void createBinTree();//按给定方法输入一棵二叉树(层序)
  20. void clear();//销毁一颗二叉树
  21. void Root();//返回根节点
  22. void setRoot(E e);//设置根节点
  23. void Depthhelp(int u,int d);//求出各结点的深度 ,预处理
  24. bool isEmpty();//判断二叉树是否为空
  25. void preorder(int u);//前序遍历
  26. //void inorder(int u);//中序遍历
  27. void postorder(int u);//后序遍历
  28. void levelorder(int u);//层次遍历
  29. int BinTreeDepth();//二叉树高度
  30. int count(int u);//二叉树结点数
  31. };
  32. }
  33. #endif

3、BinTree.cpp

  1. #include<iostream>
  2. #include<queue>
  3. #include<algorithm>
  4. using namespace std;
  5. #include"BinTree.h"
  6. namespace wangzhe
  7. {
  8. template<typename E>
  9. BinTree<E>::BinTree(int sz)
  10. {
  11. T=new BinNode<E>[sz];
  12. D=new int[sz];
  13. for(int i=0;i<sz;i++)//一开始都没有子结点和兄弟结点
  14. {
  15. D[i]=-1;
  16. }
  17. size=sz;
  18. height=0;
  19. }
  20. template<typename E>
  21. BinTree<E>::~BinTree()
  22. {
  23. clear();
  24. }
  25. template<typename E>
  26. void BinTree<E>::createBinTree()
  27. {
  28. if(D[0]==-1)
  29. {
  30. cout<<"该树无根结点,为空树\n";
  31. return;
  32. }
  33. int cnt=0;
  34. E p,c;//父结点数据,子结点数据
  35. queue< BinNode<E>* > que;
  36. que.push(&T[0]);
  37. while(cin>>p>>c)
  38. {
  39. if(p=='#'&&c=='#') break;
  40. cnt++;
  41. if(cnt+1>size)
  42. {
  43. cout<<"结点数超限\n"; break;
  44. }
  45. while(que.front()->element()!=p&&!que.empty()) {que.pop();}
  46. if(que.empty())
  47. {
  48. cout<<"结点不匹配\n";
  49. break;//不能连成树
  50. }
  51. if(que.front()->left()==-1)//最左
  52. {
  53. T[cnt].setElement(c);
  54. que.front()->setLeft(cnt);
  55. que.push(&T[cnt]);
  56. }
  57. else//右邻
  58. {
  59. T[cnt].setElement(c);
  60. int x=que.front()->left();
  61. while(T[x].right()!=-1) x=T[x].right();
  62. T[x].setRight(cnt);
  63. que.push(&T[cnt]);
  64. }
  65. }
  66. }
  67. template<typename E>
  68. void BinTree<E>::clear()
  69. {
  70. delete [] T;
  71. }
  72. template<typename E>
  73. void BinTree<E>::setRoot(E e)
  74. {
  75. T[0].setElement(e);
  76. D[0]=0;
  77. }
  78. template<typename E>
  79. void BinTree<E>::Depthhelp(int u,int d)
  80. {
  81. D[u]=d;
  82. if(T[u].left()!=-1) Depthhelp(T[u].left(),d+1);
  83. if(T[u].right()!=-1) Depthhelp(T[u].right(),d);
  84. height=max(height,d);
  85. }
  86. template<typename E>
  87. bool BinTree<E>::isEmpty()
  88. {
  89. return D[0]==-1;
  90. }
  91. template<typename E>
  92. void BinTree<E>::preorder(int u)
  93. {
  94. if(u==-1) return;
  95. cout<<T[u].element()<<' ';
  96. preorder(T[u].left());
  97. preorder(T[u].right());
  98. }
  99. template<typename E>
  100. void BinTree<E>::postorder(int u)
  101. {
  102. if(u==-1) return;
  103. postorder(T[u].left());
  104. cout<<T[u].element()<<' ';
  105. postorder(T[u].right());
  106. }
  107. template<typename E>
  108. void BinTree<E>::levelorder(int u)
  109. {
  110. int n=count(0);
  111. for(int i=0;i<n;i++)
  112. cout<<T[i].element()<<' ';
  113. }
  114. template<typename E>
  115. int BinTree<E>::BinTreeDepth()//高度 要+1
  116. {
  117. return height+1;
  118. }
  119. template<typename E>
  120. int BinTree<E>::count(int u)
  121. {
  122. if(u==-1) return 0;
  123. return 1+count(T[u].left())+count(T[u].right());
  124. }
  125. }

4、main.cpp

  1. #include <iostream>
  2. using namespace std;
  3. /* run this program using the console pauser or add your own getch, system("pause") or input loop */
  4. #include"BinTree.h"
  5. #include"BinTree.cpp"
  6. using namespace wangzhe;
  7. int main(int argc, char** argv)
  8. {
  9. for(int i=1;i<=50;i++) cout<<'*';
  10. cout<<"\n实验三:二叉树的物理实现(顺序表、左子右兄弟)\n";
  11. for(int i=1;i<=50;i++) cout<<'*';
  12. cout<<"\n请输入根节点数据:\n";
  13. char r;
  14. cin>>r;
  15. BinTree<char> Tree(101);
  16. Tree.setRoot(r);
  17. cout<<"请以层序依次输入各子结点数据(以# #作为结束标志):";
  18. cout<<"\n(数据类型为单个字符,如输入A B表示父结点数据是A,有一个子结点数据是B)\n" ;
  19. Tree.createBinTree();
  20. Tree.Depthhelp(0,0); //预处理
  21. cout<<"\n这棵二叉树前序遍历的结果为:\n";
  22. Tree.preorder(0);
  23. cout<<"\n这棵二叉树后序遍历的结果为:\n" ;
  24. Tree.postorder(0);
  25. cout<<"\n这棵二叉树层次遍历的结果为:\n" ;
  26. Tree.levelorder(0);
  27. cout<<"\n这棵二叉树的高度是:\n" ;
  28. cout<<Tree.BinTreeDepth();
  29. cout<<"\n这棵二叉树的结点个数是:\n" ;
  30. cout<<Tree.count(0)<<endl;
  31. return 0;
  32. /*A
  33. A B
  34. A C
  35. B D
  36. B E
  37. C G
  38. C H
  39. # # */
  40. }

5、运行结果

 

三、参考资料

1、姬小野_有根树的表达_左子右兄弟表示法

2、zhou2214_树的左孩子 右兄弟表示法的建立过程 (后序遍历)

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

闽ICP备14008679号