题目描述

已知二叉链表类,请实现二叉树的先序、中序、后序递归遍历。
//OJ-1020 binary tree(1)
#include
#include
using namespace std;
//二叉树类,实现二叉树的递归算法:三种遍历
template
struct BiNode //二叉树的结点结构
{
DataType data;
BiNode lchild, rchild;
};
template
class BiTree{
public:
BiTree(); //构造函数,初始化一棵二叉树,其前序序列由键盘输入
~BiTree(); //析构函数,释放二叉链表中各结点的存储空间
void PreOrder(void); //调用私有的递归函数PerOrder
void InOrder(void);
void PostOrder(void);
private:
BiNode root; //指向根结点的头指针
void Creat(BiNode
&bt);//被构造函数调用,递归方式生成二叉树
void Release(BiNode &bt); //被析构函数调用
void PreOrder(BiNode
bt); //前序遍历二叉树
void InOrder(BiNode bt); //中序遍历二叉树
void PostOrder(BiNode
bt); //后序遍历二叉树
};
//定义类中的成员函数
//构造函数:Creat利用创建二叉树
template
BiTree::BiTree()
{
Creat(root);
}
//功 能:递归方法创建一棵二叉树,由构造函数调用
template
void BiTree::Creat(BiNode &bt)
{
DataType ch;
cin>>ch;
if (ch==”#”) bt = nullptr; //创建结点值为字符串的二叉树
else{
bt = new BiNode; //生成一个结点
bt->data=ch;
Creat(bt->lchild); //递归建立左子树
Creat(bt->rchild); //递归建立右子树
}
}
//功 能:析构函数,释放二叉链表中各结点的存储空间
template
BiTree::~BiTree() //析构函数不能带参数
{
Release(root);
}
//功 能:释放二叉树的存储空间,析构函数调用
template
void BiTree::Release(BiNode
&bt)
{
if (bt != nullptr){
Release(bt->lchild); //释放左子树
Release(bt->rchild); //释放右子树
delete bt;
}
}
template
void BiTree::PreOrder(void)
{
PreOrder(root);
}
template
void BiTree::InOrder(void)
{
InOrder(root);
}
template
void BiTree::PostOrder(void)
{
PostOrder(root);
}
//请在下面补充实现二叉树的三种递归遍历算法

int main()
{
BiTree mybit;
mybit.PreOrder();
cout<mybit.InOrder();
cout<mybit.PostOrder();
cout<return 0;
}

输入

输出

样例输入

Li Sun # Zhao Zhou # # Wang # # Qian # #

样例输出

Li Sun Zhao Zhou Wang Qian Sun Zhou Zhao Wang Li Qian Zhou Wang Zhao Sun Qian Li

提示

来源

提交

  1. import java.util.Scanner;
  2. class Node {
  3. public Object data;
  4. public Node next;
  5. public Node() {
  6. this(null,null);
  7. }
  8. public Node(Object data) {
  9. this(data,null);
  10. }
  11. public Node(Object data, Node next) {
  12. this.data = data;
  13. this.next = next;
  14. }
  15. }
  16. class LinkStack{
  17. private Node top; // 栈顶元素的引用
  18. // 将一个已经存在的栈置成空
  19. public void clear() {
  20. top = null;
  21. }
  22. // 测试栈是否为空
  23. public boolean isEmpty() {
  24. return top == null;
  25. }
  26. // 求栈中的数据元素个数并由函数返回其值
  27. public int length() {
  28. Node p = top;// 初始化,p指向栈顶结点,length为计数器
  29. int length = 0;
  30. while (p != null) {// 从栈顶结点向后查找,直到p指向栈顶结点
  31. p = p.next;// 指向后继结点
  32. ++length;// 长度增1
  33. }
  34. return length;
  35. }
  36. // 查看栈顶对象而不移除它,返回栈顶对象
  37. public Object peek() {
  38. if (!isEmpty())
  39. return top.data;// 返回栈顶元素
  40. else
  41. return null;
  42. }
  43. // 移除栈顶对象并作为此函数的值返回该对象
  44. public Object pop() {
  45. if (!isEmpty()) {
  46. Node p = top;// p指向栈顶结点
  47. top = top.next;
  48. return p.data;
  49. } else
  50. return null;
  51. }
  52. // 把项压入栈顶
  53. public void push(Object x) {
  54. Node p = new Node(x); // 构造一个新的结点
  55. p.next=top;
  56. top = p;// 改变栈顶结点
  57. }
  58. // 打印函数,打印所有栈中的元素(栈顶到栈底)
  59. public void display() {
  60. Node p = top; // p指向栈顶结点,q指向p的下一结点
  61. while (p != null) {// 打印所有非空的结点
  62. System.out.print((p.data.toString() + " ")); // 打印
  63. p = p.next;// 指向p下一元素
  64. }
  65. }
  66. }
  67. class LinkQueue{
  68. private Node front;
  69. private Node rear;
  70. public LinkQueue() {
  71. front = rear = null;
  72. }
  73. public void clear() {
  74. front = rear = null;
  75. }
  76. public boolean isEmpty() {
  77. return front == null;
  78. }
  79. public int length() {
  80. Node p = front;
  81. int length = 0;
  82. while (p != null) {
  83. p = p.next;
  84. ++length;
  85. }
  86. return length;
  87. }
  88. public void offer(Object o) {
  89. Node p = new Node(o);
  90. if (front != null) {
  91. rear.next=p;
  92. rear = p;
  93. } else
  94. front = rear = p;
  95. }
  96. public Object peek() {
  97. if (front != null)
  98. return front.data;
  99. else
  100. return null;
  101. }
  102. public Object poll() {
  103. if (front != null) {
  104. Node p = front;
  105. front = front.next;
  106. if (p==rear)
  107. rear=null;
  108. return p.data;
  109. } else
  110. return null;
  111. }
  112. public void display() {
  113. if (!isEmpty()) {
  114. Node p = front;
  115. while (p != rear.next) {
  116. System.out.print(p.data.toString() + " ");
  117. p = p.next;
  118. }
  119. } else {
  120. System.out.println("此队列为空");
  121. }
  122. }
  123. }
  124. class BiTreeNode {
  125. public Object data;// 结点的数据元素
  126. public BiTreeNode lchild, rchild; // 左右孩子
  127. public BiTreeNode() {// 构造一个空结点
  128. this(null);
  129. }
  130. public BiTreeNode(Object data) {// 构造一棵左右孩子为空的结点
  131. this(data, null, null);
  132. }
  133. public BiTreeNode(Object data, BiTreeNode lchild, BiTreeNode rchild) {// 构造一棵数据元素和左右孩子都不为空的结点
  134. this.data = data;
  135. this.lchild = lchild;
  136. this.rchild = rchild;
  137. }
  138. }
  139. class BiTree {
  140. private BiTreeNode root;// 树的根结点
  141. public BiTree() {// 构造一棵空树
  142. this.root = null;
  143. }
  144. public BiTree(BiTreeNode root) {// 构造一棵树
  145. this.root = root;
  146. }
  147. // 由先根遍历的数组和中根遍历的数组建立一棵二叉树
  148. // 其中参数preOrder是整棵树的 先根遍历,inOrder是整棵树的中根遍历,preIndex是
  149. // 先根遍历从preOrder字符串中的开始位置,inIndex是中根遍历从字符串inOrder中的开始位置,count表示树结点的个数
  150. public BiTree(String preOrder, String inOrder, int preIndex, int inIndex,
  151. int count) {
  152. if (count > 0) {// 先根和中根非空
  153. char r = preOrder.charAt(preIndex);// 取先根字符串中的第一个元素作为根结点
  154. int i = 0;
  155. for (; i < count; i++)
  156. // 寻找根结点在中根遍历字符串中的索引
  157. if (r == inOrder.charAt(i + inIndex))
  158. break;
  159. root = new BiTreeNode(r);// 建立树的根结点
  160. root.lchild=new BiTree(preOrder, inOrder, preIndex + 1, inIndex,
  161. i).root;// 建立树的左子树
  162. root.rchild=new BiTree(preOrder, inOrder, preIndex + i + 1,
  163. inIndex + i + 1, count - i - 1).root;// 建立树的右子树
  164. }
  165. }
  166. // 由标明空子树的先根遍历序列建立一棵二叉树
  167. private static int index = 0;// 用于记录preStr的索引值
  168. public BiTree(String[] preStr) {
  169. String c = preStr[index++];// 取出字符串索引为index的字符,且index增1
  170. if (!c.equals("#") ) {// 字符不为#
  171. root = new BiTreeNode(c);// 建立树的根结点
  172. root.lchild=new BiTree(preStr).root;// 建立树的左子树
  173. root.rchild=new BiTree(preStr).root;// 建立树的右子树
  174. } else
  175. root = null;
  176. }
  177. // 先根遍历二叉树基本操作的递归算法
  178. public void preRootTraverse(BiTreeNode T) {
  179. if (T != null) {
  180. System.out.print(T.data); // 访问根结点
  181. preRootTraverse(T.lchild);// 访问左子树
  182. preRootTraverse(T.rchild);// 访问右子树
  183. }
  184. }
  185. // 先根遍历二叉树基本操作的非递归算法
  186. public void preRootTraverse() {
  187. BiTreeNode T = root;
  188. if (T != null) {
  189. LinkStack S = new LinkStack();// 构造栈
  190. S.push(T);// 根结点入栈
  191. while (!S.isEmpty()) {
  192. T = (BiTreeNode) S.pop();// 移除栈顶结点,并返回其值
  193. System.out.print(T.data +" "); // 访问结点
  194. while (T != null) {
  195. if (T.lchild != null) // 访问左孩子
  196. System.out.print(T.lchild.data +" "); // 访问结点
  197. if (T.rchild != null)// 右孩子非空入栈
  198. S.push(T.rchild);
  199. T = T.lchild;
  200. }
  201. }
  202. }
  203. }
  204. // 中根遍历二叉树基本操作的递归算法
  205. public void inRootTraverse(BiTreeNode T) {
  206. if (T != null) {
  207. inRootTraverse(T.lchild);// 访问左子树
  208. System.out.print(T.data); // 访问根结点
  209. inRootTraverse(T.rchild);// 访问右子树
  210. }
  211. }
  212. // 中根遍历二叉树基本操作的非递归算法
  213. public void inRootTraverse() {
  214. BiTreeNode T = root;
  215. if (T != null) {
  216. LinkStack S = new LinkStack();// 构造链栈
  217. S.push(T); // 根结点入栈
  218. while (!S.isEmpty()) {
  219. while (S.peek() != null)
  220. // 将栈顶结点的所有左孩子结点入栈
  221. S.push(((BiTreeNode) S.peek()).lchild);
  222. S.pop(); // 空结点退栈
  223. if (!S.isEmpty()) {
  224. T = (BiTreeNode) S.pop();// 移除栈顶结点,并返回其值
  225. System.out.print(T.data +" "); // 访问结点
  226. S.push(T.rchild);// 结点的右孩子入栈
  227. }
  228. }
  229. }
  230. }
  231. // 后根遍历二叉树基本操作的递归算法
  232. public void postRootTraverse(BiTreeNode T) {
  233. if (T != null) {
  234. postRootTraverse(T.lchild);// 访问左子树
  235. postRootTraverse(T.rchild);// 访问右子树
  236. System.out.print(T.data); // 访问根结点
  237. }
  238. }
  239. // 后根遍历二叉树基本操作的非递归算法
  240. public void postRootTraverse() {
  241. BiTreeNode T = root;
  242. if (T != null) {
  243. LinkStack S = new LinkStack();// 构造链栈
  244. S.push(T); // 根结点进栈
  245. Boolean flag;// 访问标记
  246. BiTreeNode p = null;// p指向刚被访问的结点
  247. while (!S.isEmpty()) {
  248. while (S.peek() != null)
  249. // 将栈顶结点的所有左孩子结点入栈
  250. S.push(((BiTreeNode) S.peek()).lchild);
  251. S.pop(); // 空结点退栈
  252. while (!S.isEmpty()) {
  253. T = (BiTreeNode) S.peek();// 查看栈顶元素
  254. if (T.rchild == null || T.rchild == p) {
  255. System.out.print(T.data +" "); // 访问结点
  256. S.pop();// 移除栈顶元素
  257. p = T;// p指向刚被访问的结点
  258. flag = true;// 设置访问标记
  259. } else {
  260. S.push(T.rchild);// 右孩子结点入栈
  261. flag = false;// 设置未被访问标记
  262. }
  263. if (!flag)
  264. break;
  265. }
  266. }
  267. }
  268. }
  269. // 层次遍历二叉树基本操作的算法(自左向右)
  270. public void levelTraverse() {
  271. BiTreeNode T = root;
  272. if (T != null) {
  273. LinkQueue L = new LinkQueue();// 构造队列
  274. L.offer(T);// 根结点入队列
  275. while (!L.isEmpty()) {
  276. T = (BiTreeNode) L.poll();
  277. System.out.print(T.data); // 访问结点
  278. if (T.lchild != null)// 左孩子非空,入队列
  279. L.offer(T.lchild);
  280. if (T.rchild != null)// 右孩子非空,入队列
  281. L.offer(T.rchild);
  282. }
  283. }
  284. }
  285. public BiTreeNode getRoot() {
  286. return root;
  287. }
  288. public void setRoot(BiTreeNode root) {
  289. this.root = root;
  290. }
  291. // 统计叶结点数目
  292. public int countLeafNode(BiTreeNode T) {
  293. int count = 0;
  294. if (T != null) {
  295. if (T.lchild == null && T.rchild == null) {
  296. ++count;// 叶结点个数加1
  297. } else {
  298. count += countLeafNode(T.lchild); // 加上左子树上叶结点的个数
  299. count += countLeafNode(T.rchild);// 加上右子树上叶结点的个数
  300. }
  301. }
  302. return count;
  303. }
  304. // 统计结点的数目
  305. public int countNode(BiTreeNode T) {
  306. int count = 0;
  307. if (T != null) {
  308. ++count;// 结点的个数加1
  309. count += countNode(T.lchild); // 加上左子树上结点的个数
  310. count += countNode(T.rchild);// 加上右子树上结点的个数
  311. }
  312. return count;
  313. }
  314. }
  315. public class Main {
  316. public static void main(String[] args) {
  317. // TODO Auto-generated method stub
  318. Scanner scanner = new Scanner(System.in);
  319. String s = scanner.nextLine();
  320. String[] ss = s.split(" ");
  321. BiTree b = new BiTree(ss);
  322. b.preRootTraverse();
  323. System.out.println();
  324. b.inRootTraverse();
  325. System.out.println();
  326. b.postRootTraverse();
  327. }
  328. }