树  0.1
数据结构_第6章
binaryTree.hh
Go to the documentation of this file.
1 /****************************************************
2  * @file binaryTree.hh
3  * @author Guorui Wei (313017602@qq.com)
4  * @brief 二叉树的二叉链表实现
5  * @version 0.1
6  * @date 2020-04-19
7  *
8  * @copyright Copyright (c) 2020
9  *
10  * See the file LICENSE in the top directory of this distribution for
11  * more information.
12  *
13  ****************************************************/
14 
15 #ifndef INCLUDE_BINARYTREE_HH_
16 #define INCLUDE_BINARYTREE_HH_
17 
18 #include "Queue.h"
19 #include "Stack.h"
20 #include "TreeException.hh"
21 #include "binTree.h"
22 #include <cassert>
23 #include <functional>
24 #include <iostream>
25 #include <utility>
26 
27 namespace Tree
28 {
40 template <typename T, typename Comparator = std::less<T>>
41 class binaryTree;
42 
61 template <class T, typename Comparator>
62 void printBinaryTree(const binaryTree<T, Comparator> &bin_tree, const typename binaryTree<T, Comparator>::value_type &flag, std::ostream &out = std::cout);
63 
77 template <class T, typename Comparator>
79 
80 template <typename T, typename Comparator>
81 class binaryTree /* : binTree<T> */
82 {
88  // friend void printBinaryTree</*T, Comparator*/>(const binaryTree<T, Comparator> &bin_tree, const typename binaryTree<T, Comparator>::value_type &flag, std::ostream &out);
89  friend bool operator==</*T, Comparator*/>(const binaryTree /*<T, Comparator>*/ &lhs, const binaryTree /*<T, Comparator>*/ &rhs);
90 
91 public:
96  typedef T value_type;
97  typedef value_type &reference;
98  typedef const value_type &const_reference;
99  typedef size_t size_type;
100 
101  friend void printBinaryTree</*T, Comparator*/>(const binaryTree /*<T, Comparator>*/ &bin_tree, const typename binaryTree /*<T, Comparator>*/ ::value_type &flag, std::ostream &out);
102 
103 private:
108  struct BinNode
109  {
112  BinNode *right;
113 
121  explicit BinNode(const value_type &_data = value_type{}, BinNode *_left = nullptr, BinNode *_right = nullptr) : data(_data), left(_left), right(_right) {}
122 
130  explicit BinNode(value_type &&_data, BinNode *_left, BinNode *_right) : data(std::move(_data)), left(_left), right(_right) {}
131 
136  ~BinNode() = default;
137  };
138 
139  BinNode *root_;
140 
141 public:
148  binaryTree() : root_(nullptr){};
149 
157  explicit binaryTree(const value_type &x) : root_(new BinNode(x)) {}
158 
165  binaryTree(const binaryTree &rhs) : binaryTree() { root_ = clone(rhs.root_); }
166 
173  binaryTree &operator=(const binaryTree &rhs)
174  {
175  // 这种模式可消除对自身赋值的特殊情况
176  binaryTree copy = rhs; // 要调用复制构造函数
177  std::swap(*this, copy); // 要调用移动构造、移动赋值函数
178  return *this;
179  }
180 
186  binaryTree(binaryTree &&rhs) : root_{rhs.root_} { rhs.root_ = nullptr; }
187 
195  {
196  // 防止自身赋值
197  if (rhs.root_ == root_)
198  return *this;
199  std::swap(root_, rhs.root_); // 交换后,原由左操作数维护的资源转至右操作数,从而将被释放
200  return *this;
201  }
202 
207  ~binaryTree();
208 
213  void clear();
214 
221  bool empty() const;
222 
229  value_type root(const value_type &flag) const;
230 
239  value_type lchild(const value_type &x, const value_type &flag) const;
240 
249  value_type rchild(const value_type &x, const value_type &flag) const;
250 
257  void delLeft(const value_type &x);
258 
265  void delRight(const value_type &x);
266 
273  void preOrder(std::ostream &out = std::cout) const;
274 
281  void preOrder_loop(/* BinNode *root, */ std::ostream &out = std::cout) const;
282 
289  void inOrder(std::ostream &out = std::cout) const;
290 
297  void inOrder_loop(/* BinNode *root, */ std::ostream &out = std::cout) const;
298 
305  void postOrder(std::ostream &out = std::cout) const;
306 
313  void postOrder_loop(/* BinNode *root, */ std::ostream &out = std::cout) const;
314 
321  void levelOrder(std::ostream &out = std::cout) const;
322 
335  void createTree(const value_type &flag = value_type{}, std::istream &in = std::cin);
336 
346  value_type parent(value_type x, const value_type &flag) const { return flag; }
347 
356  size_type height() const;
357 
368  size_type height_loop() const;
369 
375  size_type size() const;
376 
384  size_type size_loop() const;
385 
392  void swaplr() { swaplr(root_); }
393 
397  size_type CountDegreeTwo() const { return CountDegreeTwo(root_); }
398 
405  bool isCompleteTree() const;
406 
415  bool isFullBinaryTree() const;
416 
425  static bool is_symmetrical_tree(const binaryTree &lhs, const binaryTree &rhs) { return is_symmetrical_subtree(lhs.root_, rhs.root_); }
426 
427  // 基类要求实现下列API
428  /*
429  virtual value_type root(value_type flag) const;
430  virtual value_type parent(value_type x, value_type flag) const;
431  virtual value_type lchild(value_type x, value_type flag) const;
432  virtual value_type rchild(value_type x, value_type flag) const;
433  virtual void delLeft(value_type x);
434  virtual void delRight(value_type x);
435  */
436 
437 private:
448  BinNode *find(const value_type &x, BinNode *root) const;
449 
458  void clear(BinNode *&root);
459 
466  BinNode *clone(BinNode *_root) const;
467 
476  static bool is_symmetrical_subtree(BinNode *root1, BinNode *root2);
477 
485  void
486  preOrder(BinNode *root, std::ostream &out = std::cout) const;
487 
495  void inOrder(BinNode *root, std::ostream &out = std::cout) const;
496 
504  void postOrder(BinNode *root, std::ostream &out = std::cout) const;
505 
506  /* constexpr */ static Comparator is_less_than_ /* = Comparator{} */;
507 
516  static bool value_type_less(const value_type &lhs, const value_type &rhs) { return is_less_than_(lhs, rhs); }
517 
526  static bool value_type_equal(const value_type &lhs, const value_type &rhs) { return !is_less_than_(lhs, rhs) && !is_less_than_(rhs, lhs); }
527 
536  static bool value_type_less_equal(const value_type &lhs, const value_type &rhs) { return value_type_less(lhs, rhs) || value_type_equal(lhs, rhs); }
537 
545  size_type size(BinNode *_root) const;
546 
556  size_type size_loop(BinNode *_root) const;
557 
565  size_type height(BinNode *_root) const;
566 
576  size_type height_loop(BinNode *_root) const;
577 
584  size_type CountDegreeTwo(BinNode *_root) const;
585 
592  void swaplr(BinNode *_root);
593 
602  static bool is_equal_subtree(BinNode *_root1, BinNode *_root2);
603 };
604 
605 template <class T, typename Comparator>
606 Comparator binaryTree<T, Comparator>::is_less_than_ = Comparator{};
607 
608 template <class T, typename Comparator>
610 {
611  return !root_;
612 }
613 
614 template <class T, typename Comparator>
615 typename binaryTree<T, Comparator>::value_type binaryTree<T, Comparator>::root(const value_type &flag) const
616 {
617  if (root_)
618  return root_->data;
619 
620  return flag;
621 }
622 
623 template <class T, typename Comparator>
624 void binaryTree<T, Comparator>::clear(BinNode *&root)
625 {
626  if (!root)
627  return;
628 
629  clear(root->left);
630  clear(root->right);
631  delete root;
632  root = nullptr;
633 }
634 
635 template <class T, typename Comparator>
637 {
638  clear(root_);
639 }
640 
641 template <class T, typename Comparator>
643 {
644  clear(root_);
645 }
646 
647 template <class T, typename Comparator>
649 {
650  if (!_root)
651  return nullptr;
652  return new BinNode(_root->data, clone(_root->left), clone(_root->right));
653 }
654 
655 template <class T, class U>
657 {
658  // 两棵空树
659  if (!_root1 && !_root2)
660  return true;
661  // 一棵空树
662  if (!_root1 || !_root2)
663  return false;
664  // 根结点不同
665  if (!value_type_equal(_root1->data, _root2->data))
666  return false;
667  // 至此,#1和#2对称 iff. #1的左/右子树与#2的右/左子树对称
668  return is_symmetrical_subtree(_root1->left, _root2->right) && is_symmetrical_subtree(_root2->left, _root1->right);
669 }
670 
671 template <class T, class U>
672 bool binaryTree<T, U>::is_equal_subtree(BinNode *_root1, BinNode *_root2)
673 {
674  // 两棵空树
675  if (!_root1 && !_root2)
676  return true;
677  // 仅一棵为空
678  if (!_root1 || !_root2)
679  return false;
680  // 根结点不同
681  if (!value_type_equal(_root1->data, _root2->data))
682  return false;
683  return is_equal_subtree(_root1->left, _root2->left) && is_equal_subtree(_root1->right, _root2->right);
684 }
685 
686 template <typename T, typename U>
688 {
689  size_type size_of_tree = size_loop(); // 二叉树的结点数
690  size_type height_of_tree = height_loop(); // 二叉树的高度(0, 1, ...)
691  // 因高度从0起,是满二叉树iff.有2^(height+1) - 1个结点
692  // 这样使得空二叉树不是满二叉树
693  if (((size_type(1) << (height_of_tree + 1)) - 1) == size_of_tree)
694  return true;
695  return false;
696 }
697 
698 template <class T, typename Comparator>
700 {
701  // 认为空树是完全二叉树
702  if (!root_)
703  return true;
704 
705  BinNode *current_node = nullptr; // 当前结点
706  Queue::seqQueue<BinNode *> node_queue{}; // 暂存结点的队列,用于层次遍历
707  node_queue.push(root_);
708  while (!node_queue.empty())
709  {
710  current_node = node_queue.front();
711  node_queue.pop();
712  // 若当前结点无左孩子但有右孩子,则非完全二叉树
713  if (!current_node->left && current_node->right)
714  return false;
715  // 非空孩子入队
716  if (current_node->left)
717  node_queue.push(current_node->left);
718  if (current_node->right)
719  node_queue.push(current_node->right);
727  if (!current_node->left || !current_node->right)
728  {
729  // 检查后续结点是否都是叶子结点
730  while (!node_queue.empty())
731  {
732  current_node = node_queue.front();
733  node_queue.pop();
734  // 出现非叶子结点,判定为非完全二叉树
735  if (current_node->left || current_node->right)
736  return false;
737  }
738  return true;
739  }
740  } // while (!node_queue.empty())
741  // 控制不应到达此处
742  throw(TreeException("Bug in member function \"isCompleteTree\", since control should not reach here", "isCompleteTree()"));
743 }
744 
745 template <class T, typename Comparator>
746 void binaryTree<T, Comparator>::preOrder(BinNode *_root, std::ostream &out) const
747 {
748  if (!_root)
749  return;
750 
751  out << _root->data << ' ';
752  preOrder(_root->left, out);
753  preOrder(_root->right, out);
754 }
755 
756 template <class T, typename Comparator>
757 void binaryTree<T, Comparator>::preOrder_loop(/* BinNode *root, */ std::ostream &out) const
758 {
759  // (First rule)
767  typedef BinNode *SnapShotStruct;
768 
769  // (Second rule)
770  // 没有返回值,此步骤省略
771  // (Third rule)
772  Stack::seqStack<SnapShotStruct> snapshotStack;
773 
774  // (Fourth rule)
779  SnapShotStruct currentSnapshot{root_};
780  snapshotStack.push(currentSnapshot);
781 
782  // (Fifth rule)
783  while (!snapshotStack.empty())
784  {
785  currentSnapshot = snapshotStack.top();
786  snapshotStack.pop();
787 
788  // (Sixth rule)
789  // tail recursion,只需一个stage,此步省略
790 
791  // (Seventh rule)
792  if (!currentSnapshot)
793  {
794  // (Eighth rule)
795  // 无返回值,此步骤省略
796  // (Ninth rule)
797  continue;
798  }
799  out << currentSnapshot->data << ' ';
800 
801  // (Tenth rule)
808  if (currentSnapshot->right)
809  snapshotStack.push(currentSnapshot->right);
810  if (currentSnapshot->left)
811  snapshotStack.push(currentSnapshot->left);
812 
813  // (Ninth rule)
814  continue;
815  } // while (!snapshotStack.empty())
816 }
817 
818 template <class T, typename Comparator>
819 void binaryTree<T, Comparator>::preOrder(std::ostream &out) const
820 {
821  preOrder(root_, out);
822 }
823 
824 template <class T, typename Comparator>
825 void binaryTree<T, Comparator>::inOrder(BinNode *root, std::ostream &out) const
826 {
827  if (!root)
828  return;
829 
830  inOrder(root->left, out);
831  out << root->data << ' ';
832  inOrder(root->right, out);
833 }
834 
835 template <class T, typename Comparator>
836 void binaryTree<T, Comparator>::inOrder_loop(/* BinNode *root, */ std::ostream &out) const
837 {
838  // (First rule)
839  struct SnapShotStruct
840  {
841  BinNode *root;
842  int stage;
843  };
844 
845  // (Third rule)
846  Stack::seqStack<SnapShotStruct> snapshotStack;
847 
848  // (Fourth rule)
849  SnapShotStruct currentSnapshot{root_, 0};
850  snapshotStack.push(currentSnapshot);
851 
852  // (Fifth rule)
853  while (!snapshotStack.empty())
854  {
855  currentSnapshot = snapshotStack.top();
856  snapshotStack.pop();
857 
858  // (Sixth rule)
859  switch (currentSnapshot.stage)
860  {
861  case 0:
862  {
863  // (Seventh rule)
864  if (!currentSnapshot.root)
865  {
866  // (Ninth rule)
867  continue;
868  }
869  // (Tenth rule)
870  currentSnapshot.stage = 1;
871  snapshotStack.push(currentSnapshot);
872  snapshotStack.push(SnapShotStruct{currentSnapshot.root->left, 0});
873  break;
874  }
875  case 1:
876  {
877  // (Seventh rule)
878  out << currentSnapshot.root->data << ' ';
879  snapshotStack.push(SnapShotStruct{currentSnapshot.root->right, 0});
880  // (Ninth rule)
881  continue;
882  break;
883  }
884  default:
885  {
886  assert(false);
887  }
888  } // switch (currentSnapshot.stage)
889 
890  } /* while (!snapshotStack.empty()) */
891 }
892 
893 template <class T, typename Comparator>
894 void binaryTree<T, Comparator>::inOrder(std::ostream &out) const
895 {
896  inOrder(root_, out);
897 }
898 
899 template <class T, typename Comparator>
900 void binaryTree<T, Comparator>::postOrder(BinNode *root, std::ostream &out) const
901 {
902  if (!root)
903  return;
904 
905  postOrder(root->left, out);
906  postOrder(root->right, out);
907  out << root->data << ' ';
908 }
909 
910 template <class T, typename Comparator>
911 void binaryTree<T, Comparator>::postOrder_loop(/* BinNode *root, */ std::ostream &out) const
912 {
913  // (First rule)
914  struct SnapShotStruct
915  {
916  BinNode *root;
917  int stage;
918  };
919 
920  // (Third rule)
921  Stack::seqStack<SnapShotStruct> snapshotStack;
922 
923  // (Fourth rule)
924  SnapShotStruct currentSnapshot{root_, 0};
925  snapshotStack.push(currentSnapshot);
926 
927  // (Fifth rule)
928  while (!snapshotStack.empty())
929  {
930  currentSnapshot = snapshotStack.top();
931  snapshotStack.pop();
932 
933  // (Sixth rule)
934  switch (currentSnapshot.stage)
935  {
936  case 0:
937  {
938  // (Seventh rule)
939  if (!currentSnapshot.root)
940  {
941  // (Ninth rule)
942  continue;
943  }
944  // (Tenth rule)
945  currentSnapshot.stage = 1;
946  snapshotStack.push(currentSnapshot);
950  snapshotStack.push(SnapShotStruct{currentSnapshot.root->right, 0});
951  snapshotStack.push(SnapShotStruct{currentSnapshot.root->left, 0});
952  break;
953  }
954  case 1:
955  {
956  // (Seventh rule)
957  out << currentSnapshot.root->data << ' ';
958  // (Ninth rule)
959  continue;
960  break;
961  }
962  default:
963  {
964  assert(false);
965  }
966  } // switch (currentSnapshot.stage)
967 
968  } /* while (!snapshotStack.empty()) */
969 }
970 
971 template <class T, typename Comparator>
972 void binaryTree<T, Comparator>::postOrder(std::ostream &out) const
973 {
974  postOrder(root_, out);
975 }
976 
977 template <class T, typename Comparator>
978 void binaryTree<T, Comparator>::levelOrder(std::ostream &out) const
979 {
980  if (!root_)
981  return;
982 
983  BinNode *current_node = nullptr;
985  node_queue.push(root_);
986 
987  while (!node_queue.empty())
988  {
989  current_node = node_queue.front();
990  node_queue.pop();
991 
992  if (current_node->left)
993  node_queue.push(current_node->left);
994 
995  if (current_node->right)
996  node_queue.push(current_node->right);
997 
998  out << current_node->data << ' ';
999  }
1000 }
1001 
1002 template <class T, typename Comparator>
1003 typename binaryTree<T, Comparator>::BinNode *binaryTree<T, Comparator>::find(const value_type &x, BinNode *root) const
1004 {
1005  if (!root)
1006  return nullptr;
1007 
1008  if (value_type_equal(root->data, x))
1009  return root;
1010 
1011  BinNode *target = nullptr;
1012  if ((target = find(x, root->left)))
1013  return target;
1014 
1015  return find(x, root->right);
1016 }
1017 
1018 template <class T, typename Comparator>
1019 void binaryTree<T, Comparator>::delLeft(const value_type &x)
1020 {
1021  BinNode *target = find(x, root_);
1022  if (!target)
1023  return;
1024 
1025  clear(target->left);
1026 }
1027 
1028 template <class T, typename Comparator>
1029 void binaryTree<T, Comparator>::delRight(const value_type &x)
1030 {
1031  BinNode *target = find(x, root_);
1032  if (!target)
1033  return;
1034 
1035  clear(target->right);
1036 }
1037 
1038 template <class T, typename Comparator>
1039 typename binaryTree<T, Comparator>::value_type binaryTree<T, Comparator>::lchild(const value_type &x, const value_type &flag) const
1040 {
1041  BinNode *target = find(x, root_);
1042  if (!target || !target->left)
1043  return flag;
1044 
1045  return target->left->data;
1046 }
1047 
1048 template <class T, typename Comparator>
1049 typename binaryTree<T, Comparator>::value_type binaryTree<T, Comparator>::rchild(const value_type &x, const value_type &flag) const
1050 {
1051  BinNode *target = find(x, root_);
1052  if (!target || !target->right)
1053  return flag;
1054 
1055  return target->right->data;
1056 }
1057 
1058 template <class T, typename Comparator>
1059 void binaryTree<T, Comparator>::swaplr(BinNode *_root)
1060 {
1061  if (!_root)
1062  return;
1063 
1064  swaplr(_root->left);
1065  swaplr(_root->right);
1066  std::swap(_root->left, _root->right);
1067 }
1068 
1069 template <class T, typename Comparator>
1072  // 若为空树,或无叶子结点,则返回0
1073  if (!_root || (!_root->left && !_root->right))
1074  return 0;
1075 
1076  return static_cast<size_type>(_root->left && _root->right) + CountDegreeTwo(_root->left) + CountDegreeTwo(_root->right);
1077 }
1078 
1079 template <class T, typename Comparator>
1081 binaryTree<T, Comparator>::height(BinNode *_root) const
1083  if (!_root || (!_root->left && !_root->right)) // warning: suggest parentheses around '&&' within '||' [-Wparentheses]
1084  return 0;
1085 
1086  size_type left_height = height(_root->left);
1087  size_type right_height = height(_root->right);
1088  return 1 + ((left_height > right_height) ? left_height : right_height);
1089 }
1090 
1091 template <class T, typename Comparator>
1094  // (First rule)
1095  struct SnapShotStruct // this can be declared as local structure since it will be only used within this function.
1096  {
1097  // 不要初始化struct的成员!否则无法使用初始化列表,除非定义构造函数
1098  BinNode *_root; // parameter that changes
1099  size_type left_height; // the local variable that changes
1100  size_type right_height; // the local variable that changes
1101  int stage; // the stage variable to track where the snapshot has taken
1102  };
1103 
1104  // (Second rule)
1105  size_type returnVal; // the return value at the point
1106 
1107  // (Third rule)
1108  Stack::seqStack<SnapShotStruct> snapshotStack{};
1109 
1110  // (Fourth rule)
1111  SnapShotStruct currentSnapshot{__root, 0, 0, 0}; // as initial stage
1112  snapshotStack.push(currentSnapshot);
1113 
1114  // (Fifth rule)
1115  while (!snapshotStack.empty())
1116  {
1117  currentSnapshot = snapshotStack.top();
1118  snapshotStack.pop();
1119 
1120  // (Sixth rule)
1121  switch (currentSnapshot.stage)
1122  {
1123  // (Seventh rule)
1124  case 0:
1125  {
1126  if (!currentSnapshot._root || (!currentSnapshot._root->left && !currentSnapshot._root->right))
1127  {
1128  // (Eighth rule && Ninth rule)
1129  returnVal = 0;
1130  continue;
1131  }
1132 
1133  // (Tenth rule)
1134  currentSnapshot.stage = 1; // current snapshot is done processing and only waiting for result of calling itself, so becomes stage "1"
1135  snapshotStack.push(currentSnapshot);
1136 
1137  // Create a new snapshot for calling itself
1138  SnapShotStruct newSnapshot{currentSnapshot._root->left, 0, 0, 0}; // give parameter as parameter given when calling itself (first case height(_root->left)). Since it will start from the beginning of the function, give the initial stage
1139  snapshotStack.push(newSnapshot);
1140  continue;
1141 
1142  break;
1143  }
1144  // (Seventh rule)
1145  case 1:
1146  {
1147  // (Tenth rule)
1148  currentSnapshot.left_height = returnVal;
1149  currentSnapshot.stage = 2;
1150  snapshotStack.push(currentSnapshot);
1151 
1152  // Create a new snapshot for calling itself
1153  SnapShotStruct newSnapshot{currentSnapshot._root->right, 0, 0, 0}; // give parameter as parameter given when calling itself (first case height(_root->right)). Since it will start from the beginning of the function, give the initial stage
1154  snapshotStack.push(newSnapshot);
1155  continue;
1156 
1157  break;
1158  }
1159  case 2:
1160  {
1161  // (Seventh rule)
1162  currentSnapshot.right_height = returnVal;
1163 
1164  // (Eighth rule)
1165  returnVal = 1 + ((currentSnapshot.left_height > currentSnapshot.right_height) ? currentSnapshot.left_height : currentSnapshot.right_height);
1166 
1167  // (Ninth rule)
1168  continue;
1169  }
1170  default:
1171  {
1172  assert(false);
1173  }
1174  } // switch (currentSnapshot.stage)
1175 
1176  } // while (!snapshotStack.empty())
1177 
1178  // (Second rule)
1179  return returnVal;
1180 }
1181 
1182 template <class T, typename Comparator>
1184 {
1185  return height(root_);
1186 }
1187 
1188 template <class T, typename Comparator>
1190 {
1191  return height_loop(root_);
1192 }
1193 
1194 template <class T, typename Comparator>
1196 {
1197  if (!_root)
1198  return 0;
1199 
1200  // think this as
1201  // size_type addVal = size(_root->left);
1202  // addVal = 1 + addVal + size(_root->right);
1203  // return addVal;
1204  return 1 + size(_root->left) + size(_root->right);
1205 }
1206 
1207 template <class T, typename Comparator>
1209 {
1210  // (First rule)
1211  struct SnapShotStruct
1212  {
1213  // 不要初始化struct的成员!否则无法使用初始化列表,除非定义构造函数
1214  BinNode *_root; // - parameter input
1215  size_type addVal; // - local variable that will be used after returning from the function call
1216  int stage; // - Since there is process needed to be done after recursive call. (Sixth rule)
1217  };
1218 
1219  // (Second rule)
1220  size_type returnVal{0}; // This value will represent the role of the return function in the recursive function.
1221 
1222  // (Third rule)
1223  Stack::seqStack<SnapShotStruct> snapshotStack{};
1224 
1225  // (Fourth rule)
1226  SnapShotStruct currentSnapshot{__root, 0, 0};
1227  snapshotStack.push(currentSnapshot);
1228 
1229  // (Fifth rule)
1230  while (!snapshotStack.empty())
1231  {
1232  currentSnapshot = snapshotStack.top();
1233  snapshotStack.pop();
1234 
1235  // (Sixth rule)
1236  switch (currentSnapshot.stage)
1237  {
1238  case 0:
1239  {
1240  // (Seventh rule)
1241  if (!currentSnapshot._root)
1242  {
1243  // (Eighth rule)
1244  returnVal = 0;
1245 
1246  // (Ninth rule)
1247  continue;
1248  }
1249 
1250  // (Tenth rule)
1251  currentSnapshot.stage = 1; // - current snapshot need to process after returning from the recursive call
1252  snapshotStack.push(currentSnapshot); // - this MUST pushed into stack before new snapshot!
1253 
1254  // Create a new snapshot for calling itself ( size(_root->left); )
1255  SnapShotStruct newSnapshot{currentSnapshot._root->left, 0, 0}; // - give parameter as parameter given when calling itself. Since it will start from the beginning of the function, give the initial stage.
1256  snapshotStack.push(newSnapshot);
1257 
1258  continue;
1259  break;
1260  }
1261  case 1:
1262  {
1263  // (Seventh rule)
1264  currentSnapshot.addVal = returnVal;
1265 
1266  // (Tenth rule)
1267  currentSnapshot.stage = 2;
1268  snapshotStack.push(currentSnapshot);
1269 
1270  // Create a new snapshot for calling itself ( size(_root->right); )
1271  SnapShotStruct newSnapshot{currentSnapshot._root->right, 0, 0}; // - give parameter as parameter given when calling itself. Since it will start from the beginning of the function, give the initial stage.
1272  snapshotStack.push(newSnapshot);
1273 
1274  continue;
1275  break;
1276  }
1277  case 2:
1278  {
1279  // (Seventh rule)
1280  // (Eighth rule)
1281  returnVal = 1 + currentSnapshot.addVal + returnVal;
1282 
1283  // (Ninth rule)
1284  continue;
1285  break;
1286  }
1287  default:
1288  {
1289  assert(false);
1290  }
1291  } // switch (currentSnapshot.stage)
1292 
1293  } // while (!snapshotStack.empty())
1294 
1295  // (Second rule)
1296  return returnVal;
1297 }
1298 
1299 template <class T, typename Comparator>
1301 {
1302  return size(root_);
1303 }
1304 
1305 template <class T, typename Comparator>
1307 {
1308  return size_loop(root_);
1309 }
1310 
1311 template <class T, typename Comparator>
1312 void binaryTree<T, Comparator>::createTree(const value_type &flag, std::istream &in)
1313 {
1314  clear();
1315 
1316  BinNode *this_node{}; // 正在处理的结点
1317  value_type this_data = flag; // 暂存数据
1318  Queue::linkQueue<BinNode *> node_queue{}; // 存放待处理(data已定而child待定)结点的队列
1319 
1320  // 要求从终端输入一个合法数据,作为根结点的data
1321  do
1322  {
1323  std::cout << "\n请输入根结点: ";
1324  in >> this_data;
1325 
1326  // 若为非法输入,或输入了代表空结点的特殊标记flag,则要求重新输入
1327  if (std::cin.fail() || value_type_equal(this_data, flag))
1328  {
1329  in.clear();
1330  in.sync();
1331  std::cerr << "根结点必须含合法数据!\n";
1332  continue;
1333  }
1334  break;
1335  } while (true);
1336 
1337  root_ = new BinNode(this_data, 0, 0);
1338  node_queue.push(root_);
1339 
1340  while (!node_queue.empty())
1341  {
1342  // 取当前结点
1343  this_node = node_queue.front();
1344  node_queue.pop();
1345 
1346  // 从终端请求当前结点的左child。若有左child,则将左child进node_queue表示待处理。
1347  this_data = flag; // 初始化数据暂存器
1348  do
1349  {
1350  std::cout << "\n请输入结点:" << this_node->data << " 的left child(输入 " << flag << " 表示无):\n";
1351  in >> this_data;
1352 
1353  // 若为非法输入,要求重新输入
1354  if (in.fail())
1355  {
1356  in.clear();
1357  in.sync(); // 读文件流sync()行为未定义?
1358  std::cerr << "非法输入!";
1359  continue;
1360  }
1361 
1362  // 若指定当前结点无左child
1363  if (value_type_equal(this_data, flag))
1364  {
1365  in.sync(); // 读文件流sync()行为未定义?
1366  std::cout << "已指定该结点无left child\n";
1367  break;
1368  }
1369 
1370  // 当前结点有左child,则将左child连到parent上,然后将左child入队列(表示左child的children待定)
1371  std::cout << "已指定左child为:" << this_data << '\n';
1372  node_queue.push(this_node->left = new BinNode(this_data, 0, 0));
1373 
1374  break;
1375  } while (true);
1376 
1377  // 从终端请求当前结点的右child。若有右child,则将右child进node_queue表示待处理。
1378  this_data = flag; // 初始化数据暂存器
1379  do
1380  {
1381  std::cout << "\n请输入结点:" << this_node->data << " 的right child(输入 " << flag << " 表示无):\n";
1382  in >> this_data;
1383 
1384  // 若为非法输入,要求重新输入
1385  if (in.fail())
1386  {
1387  in.clear();
1388  in.sync(); // 读文件流sync()行为未定义?
1389  std::cerr << "非法输入!";
1390  continue;
1391  }
1392 
1393  // 若指定当前结点无右child
1394  if (value_type_equal(this_data, flag))
1395  {
1396  in.sync(); // 读文件流sync()行为未定义?
1397  std::cout << "已指定该结点无right child\n";
1398  break;
1399  }
1400 
1401  // 当前结点有右child,则将左child连到parent上,然后将右child入队列(表示右child的children待定)
1402  std::cout << "已指定右child为:" << this_data << '\n';
1403  node_queue.push(this_node->right = new BinNode(this_data, 0, 0));
1404 
1405  break;
1406  } while (true);
1407 
1408  /* 当前结点处理完毕,准备处理node_queue中的下个结点 */
1409 
1410  } // while (!node_queue.empty())
1411 }
1412 
1413 template <class T, typename Comparator>
1414 void printBinaryTree(const binaryTree<T, Comparator> &bin_tree, const typename binaryTree<T, Comparator>::value_type &flag, std::ostream &out)
1415 {
1416  if (bin_tree.empty())
1417  {
1418  out << "是一棵空二叉树\n";
1419  return;
1420  }
1421 
1422  out << "(层次打印) 格式:\"parent lchild rchild\" ( " << flag << " 表示空结点 )\n";
1423  Queue::seqQueue<typename binaryTree<T, Comparator>::value_type> node_data_queue{}; // 存放待打印结点的队列
1424  /*typename*/ typename binaryTree<T, Comparator>::value_type this_data = flag; // 暂存当前结点的data
1425  typename binaryTree<T, Comparator>::value_type left_data = flag; // 暂存左child的data
1426  typename binaryTree<T, Comparator>::value_type right_data = flag; // 暂存右child的data
1427 
1428  // 根结点的data入队
1429  node_data_queue.push(bin_tree.root(flag));
1430 
1431  while (!node_data_queue.empty())
1432  {
1433  // 取当前结点的data
1434  this_data = node_data_queue.front();
1435  node_data_queue.pop();
1436 
1437  // 找以当前data为data的结点的左、右child的data,并打印到标准输出设备
1438  out << this_data << '\t' << (left_data = bin_tree.lchild(this_data, flag)) << '\t' << (right_data = bin_tree.rchild(this_data, flag)) << '\n';
1439 
1440  // 若以当前data为data的结点有children,则将children入队,表示待打印
1441  if (!bin_tree.value_type_equal(left_data, flag))
1442  node_data_queue.push(left_data);
1443 
1444  if (!bin_tree.value_type_equal(right_data, flag))
1445  node_data_queue.push(right_data);
1446  }
1447 }
1448 
1449 template <class T, typename Comparator>
1450 bool operator==(const binaryTree<T, Comparator> &lhs, const binaryTree<T, Comparator> &rhs)
1451 {
1452  return binaryTree<T, Comparator>::is_equal_subtree(lhs.root_, rhs.root_);
1453 }
1454 
1455 } // namespace Tree
1456 
1457 #endif /* INCLUDE_BINARYTREE_HH_ */
binTree.h
Tree::binaryTree::size_type
size_t size_type
计数器类型
Definition: binaryTree.hh:111
Tree::binaryTree::parent
value_type parent(value_type x, const value_type &flag) const
返回数据为x的结点的parent结点
Definition: binaryTree.hh:358
Tree::binaryTree::swaplr
void swaplr()
交换左右子树
Definition: binaryTree.hh:404
Tree::binaryTree::value_type_less_equal
static bool value_type_less_equal(const value_type &lhs, const value_type &rhs)
比较value_type类型对象的大小。
Definition: binaryTree.hh:548
Tree::binaryTree::isFullBinaryTree
bool isFullBinaryTree() const
是否满二叉树
Definition: binaryTree.hh:699
Queue::seqQueue
循环队列类
Definition: seqQueue.hh:46
Tree::operator==
bool operator==(const binaryTree< T, Comparator > &lhs, const binaryTree< T, Comparator > &rhs)
比较两棵二叉树是否相同 "相同"是指:
Definition: binaryTree.hh:1462
Tree::binaryTree::rchild
value_type rchild(const value_type &x, const value_type &flag) const
获得数据为x的结点的右child
Definition: binaryTree.hh:1061
Tree::binaryTree::BinNode::left
BinNode * left
指向左child
Definition: binaryTree.hh:123
Tree::binaryTree::delRight
void delRight(const value_type &x)
删除右subtree
Definition: binaryTree.hh:1041
Tree::binaryTree::empty
bool empty() const
判断二叉树是否为空树
Definition: binaryTree.hh:621
Queue::linkQueue
链接队列类
Definition: linkQueue.hh:46
Tree::binaryTree::inOrder_loop
void inOrder_loop(std::ostream &out=std::cout) const
中序遍历(非递归版本)
Definition: binaryTree.hh:848
Tree::binaryTree::BinNode
二叉链表的结点类
Definition: binaryTree.hh:120
Tree::binaryTree::BinNode::~BinNode
~BinNode()=default
Destroy the Bin Node object.
Tree::binaryTree::BinNode::data
value_type data
数据
Definition: binaryTree.hh:122
Tree::binaryTree::value_type
T value_type
类型别名定义
Definition: binaryTree.hh:108
Tree::binaryTree::preOrder_loop
void preOrder_loop(std::ostream &out=std::cout) const
前序遍历(非递归版本)
Definition: binaryTree.hh:769
Stack::seqStack::pop
virtual T pop()
Definition: seqStack.hxx:104
Tree::binaryTree::reference
value_type & reference
数据的引用
Definition: binaryTree.hh:109
Tree::binaryTree::isCompleteTree
bool isCompleteTree() const
返回是否完全二叉树
Definition: binaryTree.hh:711
Tree::binaryTree::is_symmetrical_subtree
static bool is_symmetrical_subtree(BinNode *root1, BinNode *root2)
Internal method to 判断两棵二叉树是否相互对称
Definition: binaryTree.hh:668
Tree::binaryTree::BinNode::right
BinNode * right
指向右child
Definition: binaryTree.hh:124
Tree::binaryTree::find
BinNode * find(const value_type &x, BinNode *root) const
在以root为根的树中(前序)查找数据为x的结点,返回指向该结点的指针
Definition: binaryTree.hh:1015
Queue::seqQueue::push
void push(const value_type &val)
Inserts a new element at the end of the queue, after its current last element.
Definition: seqQueue.hh:262
Tree::binaryTree::height_loop
size_type height_loop() const
返回二叉树的高度(非递归版本)
Definition: binaryTree.hh:1201
Tree::binaryTree::size
size_type size() const
返回二叉树的结点数(递归版本)
Definition: binaryTree.hh:1312
Tree::binaryTree::levelOrder
void levelOrder(std::ostream &out=std::cout) const
层次遍历
Definition: binaryTree.hh:990
Tree
自定义的树类都在Tree名字空间内
Definition: binaryTree.hh:27
Tree::binaryTree::root
value_type root(const value_type &flag) const
返回根结点的数据
Definition: binaryTree.hh:627
Tree::binaryTree::value_type_less
static bool value_type_less(const value_type &lhs, const value_type &rhs)
比较value_type类型对象的大小。
Definition: binaryTree.hh:528
Tree::binaryTree::const_reference
const typedef value_type & const_reference
数据的常量引用
Definition: binaryTree.hh:110
Tree::binaryTree::inOrder
void inOrder(std::ostream &out=std::cout) const
中序遍历(递归版本)
Definition: binaryTree.hh:906
Tree::binaryTree::BinNode::BinNode
BinNode(const value_type &_data=value_type{}, BinNode *_left=nullptr, BinNode *_right=nullptr)
Construct a new Bin Node object.
Definition: binaryTree.hh:133
Stack::seqStack::empty
bool empty() const
Definition: seqStack.hxx:68
Tree::binaryTree::size_loop
size_type size_loop() const
返回二叉树的结点数(非递归版本)
Definition: binaryTree.hh:1318
Queue.h
Tree::binaryTree::height
size_type height() const
返回二叉树的高度(递归版本)
Definition: binaryTree.hh:1195
Tree::binaryTree::printBinaryTree
friend void printBinaryTree(const binaryTree &bin_tree, const typename binaryTree ::value_type &flag, std::ostream &out)
Tree::binaryTree::postOrder_loop
void postOrder_loop(std::ostream &out=std::cout) const
后序遍历(非递归版本)
Definition: binaryTree.hh:923
Tree::binaryTree::delLeft
void delLeft(const value_type &x)
删除左subtree
Definition: binaryTree.hh:1031
Tree::binaryTree::postOrder
void postOrder(std::ostream &out=std::cout) const
后序遍历(递归版本)
Definition: binaryTree.hh:984
Tree::binaryTree::clear
void clear()
清空二叉树 函数返回后,对象的成员root_将被置nullptr
Definition: binaryTree.hh:648
Tree::binaryTree::value_type_equal
static bool value_type_equal(const value_type &lhs, const value_type &rhs)
比较value_type类型对象的大小。
Definition: binaryTree.hh:538
Tree::binaryTree::createTree
void createTree(const value_type &flag=value_type{}, std::istream &in=std::cin)
Create a Tree object.
Definition: binaryTree.hh:1324
Tree::binaryTree::clone
BinNode * clone(BinNode *_root) const
Internal method to clone subtree.
Definition: binaryTree.hh:660
Tree::binaryTree::preOrder
void preOrder(std::ostream &out=std::cout) const
前序遍历(递归版本)
Definition: binaryTree.hh:831
Tree::binaryTree::lchild
value_type lchild(const value_type &x, const value_type &flag) const
获得数据为x的结点的左child
Definition: binaryTree.hh:1051
Stack::seqStack::top
virtual T top() const
Definition: seqStack.hxx:110
Tree::binaryTree
用二叉链表实现的二叉树类
Definition: binaryTree.hh:53
Tree::binaryTree::root_
BinNode * root_
二叉树的根结点
Definition: binaryTree.hh:151
TreeException.hh
Tree::binaryTree::is_symmetrical_tree
static bool is_symmetrical_tree(const binaryTree &lhs, const binaryTree &rhs)
判断两棵二叉树是否互为镜像 两棵二叉树#1和#2互为镜像,如果二者皆为空树;或二者根结点的值相同,且#1的左、右子树与#2的右、左子树互为镜像
Definition: binaryTree.hh:437
Tree::binaryTree::CountDegreeTwo
size_type CountDegreeTwo() const
统计树中度为2的结点的个数
Definition: binaryTree.hh:409
Tree::printBinaryTree
void printBinaryTree(const binaryTree< T, Comparator > &bin_tree, const typename binaryTree< T, Comparator >::value_type &flag, std::ostream &out=std::cout)
输出一棵二叉树
Definition: binaryTree.hh:1426
Tree::binaryTree::is_equal_subtree
static bool is_equal_subtree(BinNode *_root1, BinNode *_root2)
判断两棵二叉树是否相同 "相同"是指:两棵树的形状及对应结点的值相等
Definition: binaryTree.hh:684
Stack::seqStack::push
virtual void push(const T &elem)
Definition: seqStack.hxx:86
Tree::binaryTree::binaryTree
binaryTree()
Construct a new binary Tree object.
Definition: binaryTree.hh:160
Tree::binaryTree::operator=
binaryTree & operator=(const binaryTree &rhs)
赋值运算符重载
Definition: binaryTree.hh:185
Tree::binaryTree::is_less_than_
static Comparator is_less_than_
比较器(function object)
Definition: binaryTree.hh:518
Stack.h
Stack::seqStack
Definition: seqStack.hxx:37
Tree::binaryTree::~binaryTree
~binaryTree()
Destroy the binary Tree object.
Definition: binaryTree.hh:654