二叉树的遍历方式(递归、非递归)——Java实现

布满荆棘的人生 2022-05-12 01:46 261阅读 0赞

二叉树作为一种常用的数据结构,也是面试经常被问到的知识点,了解二叉树的结构和性质也是很有必要的,对于众多的树结构,二叉树只是入门的一种,先把二叉树理解通透,再深入学习时,会更简单一些。

二叉树的性质:

(1) 在非空二叉树中,第i层的结点总数不超过fd039245d688d43f9ed0102f7f1ed21b0ff43bf5.jpg , i>=1;

(2) 深度为h的二叉树最多有279759ee3d6d55fbec4f97416e224f4a21a4ddc8.jpg

个结点(h>=1),最少有h个结点;

(3) 对于任意一棵二叉树,如果其叶结点数为N0,而度数为2的结点总数为N2,则N0=N2+1;

(4) 具有n个结点的完全二叉树的深度为3b87e950352ac65c13170265f7f2b21193138a91.jpg (注:[ ]表示向下取整)

(5)有N个结点的完全二叉树各结点如果用顺序方式存储,则结点之间有如下关系:

若I为结点编号则 如果I>1,则其父结点的编号为I/2;

如果2*I<=N,则其左孩子(即左子树的根结点)的编号为2*I;若2*I>N,则无左孩子;

如果2*I+1<=N,则其右孩子的结点编号为2*I+1;若2*I+1>N,则无右孩子。

(6)给定N个节点,能构成h(N)种不同的二叉树。

h(N)为卡特兰数的第N项。h(n)=C(2*n,n)/(n+1)。

(7)设有i个枝点,I为所有枝点的道路长度总和,J为叶的道路长度总和J=I+2i

相关术语:

树的结点(node):包含一个数据元素及若干指向子树的分支;

孩子结点(child node):结点的子树的根称为该结点的孩子;

双亲结点:B 结点是A 结点的孩子,则A结点是B 结点的双亲;

兄弟结点:同一双亲的孩子结点; 堂兄结点:同一层上结点;

祖先结点: 从根到该结点的所经分支上的所有结点子孙结点:以某结点为根的子树中任一结点都称为该结点的子孙结点层:根结点的层定义为1;根的孩子为第二层结点,依此类推;

树的深度:树中最大的结点层

结点的度:结点子树的个数

树的度: 树中最大的结点度。

叶子结点:也叫终端结点,是度为 0 的结点;

分枝结点:度不为0的结点;

有序树:子树有序的树,如:家族树;

无序树:不考虑子树的顺序;

看完二叉树的性质和相关属于,再来看一下二叉树的遍历。二叉树有很多种遍历方法,最基本的有三种:

1.前序遍历:对于下图二叉树的前序遍历结果为:1 2 4 8 9 5 10 3 6 7

2.中序遍历:对于下图二叉树的中序遍历结果为:8 4 9 2 10 5 1 6 3 7

3.后序遍历:对于下图二叉树的后 序遍历结果为:8 9 4 10 5 2 6 7 3 1

70

一、前序遍历

基本思想:先访问根结点,再先序遍历左子树,最后再先序遍历右子树。

代码实现:

递归方法

  1. /**
  2. public class TreeNode {
  3. public int val;
  4. public TreeNode left;
  5. public TreeNode right;
  6. public TreeNode(int val) {
  7. this.val = val;
  8. }
  9. }
  10. */
  11. private void preOrderBinTree(TreeNode root) {
  12. if (root == null) return;
  13. System.out.print(root.val + " "); //输出结果 1 2 4 8 9 5 10 3 6 7
  14. if (root.left != null)
  15. preOrderBinTree(root.left);
  16. if (root.right != null)
  17. preOrderBinTree(root.right);
  18. }

非递归,用栈实现

  1. private void preIterateBinTree(TreeNode root) {
  2. if(root == null) return;
  3. Stack<TreeNode> s = new Stack<>();
  4. TreeNode node = root;
  5. while (node != null || s.size() > 0) {
  6. if (node != null) {
  7. System.out.print(node.val + " ");
  8. s.push(node);
  9. node = node.left;
  10. } else {
  11. node = s.pop();
  12. node = node.right;
  13. }
  14. }
  15. }

二、中序遍历

基本思想:先中序遍历左子树,然后再访问根结点,最后再中序遍历右子树即 左—根—右

递归方法

  1. private void inOrderBinTree(TreeNode root) {
  2. if (root == null) return;
  3. if (root.left != null)
  4. inOrderBinTree(root.left);
  5. System.out.print(root.val + " "); //输出 8 4 9 2 10 5 1 6 3 7
  6. if (root.right != null)
  7. inOrderBinTree(root.right);
  8. }

非递归,用栈实现

  1. private void inIterateBinTree(TreeNode root) {
  2. if(root == null) return;
  3. Stack<TreeNode> s = new Stack<>();
  4. TreeNode node = root;
  5. while (node != null || s.size() > 0) {
  6. if (node != null) {
  7. s.push(node);
  8. node = node.left;
  9. } else {
  10. node = s.pop();
  11. System.out.print(node.val + " ");
  12. node = node.right;
  13. }
  14. }
  15. }

三、后序遍历

基本思想:先后序遍历左子树,然后再后序遍历右子树,最后再访问根结点即 左—右—根。

递归实现

  1. private void afterOrderBinTree(TreeNode root) {
  2. if (root == null) return;
  3. if (root.left != null)
  4. afterOrderBinTree(root.left);
  5. if (root.right != null)
  6. afterOrderBinTree(root.right);
  7. System.out.print(root.val + " "); //输出 8 9 4 10 5 2 6 7 3 1
  8. }

非递归,栈实现

  1. private void afterIterateBinTree(TreeNode root) {
  2. Stack<TreeNode> stack1 = new Stack<>();
  3. Stack<Integer> stack2 = new Stack<>();
  4. int i = 1;
  5. while(root != null || !stack1.empty()) {
  6. while (root != null) {
  7. stack1.push(root);
  8. stack2.push(0);
  9. root = root.left;
  10. }
  11. while(!stack1.empty() && stack2.peek() == i)
  12. {
  13. stack2.pop();
  14. System.out.print(stack1.pop().val + " ");
  15. }
  16. if(!stack1.empty())
  17. {
  18. stack2.pop();
  19. stack2.push(1);
  20. root = stack1.peek();
  21. root = root.right;
  22. }
  23. }
  24. }

四、层次遍历

非递,队列归实现

  1. private void layerIterateBinTree(TreeNode root) {
  2. if(root == null) return;
  3. Queue<TreeNode> q = new ArrayDeque<>();
  4. TreeNode node = root;
  5. while (node != null || !q.isEmpty()) {
  6. if (node != null) {
  7. System.out.print(node.val + " "); //输出 1 2 3 4 5 6 7 8 9 10
  8. if(node.left != null)
  9. q.add(node.left);
  10. if(node.right != null)
  11. q.add(node.right);
  12. node = null;
  13. } else {
  14. node = q.remove();
  15. }
  16. }
  17. }

发表评论

表情:
评论列表 (有 0 条评论,261人围观)

还没有评论,来说两句吧...

相关阅读