2、二叉树:递归遍历

  

对二叉树而言,最为核心的操作就是遍历。遍历可以用递归的方式,也可以用循环的方式。

就递归遍历而言,又有“先序、中序、后续”三种不同的遍历顺序。通过下面的一个示意图可以从感官上来体会一下三种不同的遍历顺序:

为了学习二叉树的相关算法,首先需要构建一个二叉树的抽象类public abstract class BiTreeAbstract<T> ,该类中有一个表示结点的内部类Node,将结点的数据类型定义为泛型T以方便将其用于不同的数据类型。

  1 package com.magicode.datastructure.tree;
  2
  3 public abstract class BiTreeAbstract<T> {
  4     /**
  5      * 树的根节点。
  6      */
  7     private Node root;
  8
  9     /**
 10      * 具体的构建二叉树方法。 如果构建成功,则返回二叉树的根节点(Node); 如果构建失败,则范湖null。
 11      *
 12      * @return 二叉树的根节点Node
 13      */
 14     abstract protected Node initMethod();
 15
 16     /**
 17      * 访问二叉树中的元素节点。 如果需要终止遍历,则返回false;如果需要继续遍历下去,则返回true。
 18      *
 19      * @return
 20      */
 21     abstract protected boolean visitElem(Node node);
 22
 23     /**
 24      * 创建一个二叉树,在此方法中具体调用抽象方法initMethod来 创建一个二叉树。
 25      *
 26      * @return
 27      */
 28     public boolean createBiTree() {
 29         root = initMethod();
 30         if (root != null) {
 31             return true;
 32         }
 33         return false;
 34     };
 35
 36     /**
 37      * 递归的“先序”遍历二叉树</br> 具体会调用抽象方法visitElem来具体处理遍历过程中的元素。
 38      *
 39      * @return 遍历成功,则返回true。遍历失败,返回false。
 40      */
 41     public boolean preOrderTraverse() {
 42         return preTraverse(root);
 43     }
 44
 45     private boolean preTraverse(Node node) {
 46         if (node == null) {
 47             return true;
 48         }
 49         // 改变下面三条if语句的先后关系,就可以实现“中序”和“后序”递归遍历
 50         if (visitElem(node))
 51             if (preTraverse(node.lchild))
 52                 if (preTraverse(node.rchild))
 53                     return true;
 54         return false;
 55     }
 56
 57     public Node getRoot() {
 58         return root;
 59     }
 60
 61     /**
 62      * 节点结构
 63      */
 64     protected class Node {
 65
 66         private T elem;
 67         private Node lchild;
 68         private Node rchild;
 69
 70         public Node() {
 71         }
 72
 73         public Node(T elem) {
 74             this.elem = elem;
 75             lchild = null;
 76             rchild = null;
 77         }
 78
 79         public T getElem() {
 80             return elem;
 81         }
 82
 83         public Node getLchild() {
 84             return lchild;
 85         }
 86
 87         public Node getRchild() {
 88             return rchild;
 89         }
 90
 91         public void setElem(T elem) {
 92             this.elem = elem;
 93         }
 94
 95         public void setLchild(Node lchild) {
 96             this.lchild = lchild;
 97         }
 98
 99         public void setRchild(Node rchild) {
100             this.rchild = rchild;
101         }
102
103     }
104
105 }

BiTreeAbstract抽象类

抽象类中定义了两个功能方法:

①、public boolean createBiTree()用于构建一个二叉树,在该方法中会调用abstract protected Node initMethod()方法来具体的对构建二叉树;

②、public boolean preOrderTraverse()方法的功能是先序递归的方法来遍历二叉树,它会调用抽象方法abstract protected boolean visitElem(Node node)在遍历过程对访问的当前节点进行处理,如果想在某个结点处终止遍历,只需要在visitElem方法中返回一个false即可。

下面是一个具体的实现类,它会构建一个满二叉树:

 1 package com.magicode.datastructure.tree;
 2
 3 public class BiTree extends BiTreeAbstract<Integer> {
 4
 5     private int n = 0;
 6     private String[] dat = "1|2|3|4|0|0|5|0|0|6|7|0|0|8|0|0|9|10|11|0|0|12|0|0|13|14|0|0|15|0|0".split("\\|");
 7
 8     private Node create(String[] str) {
 9         Integer ele = Integer.parseInt(str[n]);
10         n++;
11         //0表示该孩子节点为null
12         if(ele == 0){
13             return null;
14         }
15         Node nod = new Node(ele);
16         //先构建左孩子,后构建右孩子。构建顺序于先序遍历是一致的。
17         nod.setLchild(create(str));
18         nod.setRchild(create(str));
19         return nod;
20     }
21
22     @Override
23     protected Node initMethod() {
24         Node nd = create(dat);
25         return nd;
26     }
27
28     @Override
29     protected boolean visitElem(Node node) {
30         System.out.print(node.getElem() + " ");
31         return true;
32     }
33
34     public static void main(String[] args) {
35         BiTree tree = new BiTree();
36         System.out.println(tree.createBiTree());
37
38         System.out.println();
39         System.out.println("--------先序遍历------");
40         tree.preOrderTraverse();
41
42     }
43
44 }

public class BiTree extends BiTreeAbstract

运行测试结果(中序和后序只需要依据代码说明进行修改即可实现):

时间: 2024-10-10 04:06:15

2、二叉树:递归遍历的相关文章

java 二叉树递归遍历算法

//递归中序遍历 public void inorder() { System.out.print("binaryTree递归中序遍历:"); inorderTraverseRecursion(root); System.out.println(); } //层次遍历 public void layerorder() { System.out.print("binaryTree层次遍历:"); LinkedList<Node<Integer>>

二叉树递归遍历

<!doctype html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="Generator" content="EditPlus?"> <meta name="Author" content=""> <meta name="

Java学习(十三):Java二叉树递归遍历

1 public class BinaryTree 2 { 3 public void printNode(TreeNode node) 4 { 5 System.out.print(node.getData()); 6 } 7 8 class TreeNode 9 { 10 private String data; 11 12 private TreeNode leftNode; 13 14 private TreeNode rightNode; 15 16 public TreeNode(S

二叉树学习之非递归遍历

二叉树递归遍历可谓是学过数据结构的同仁都能想一下就能写出来,但在应聘过程我们常常遇到的是写出一个二叉树非递归遍历函数,接着上篇文章写二叉树的非递归遍历,先难后易,一步一步的来. 先上代码: #include "binarytree.h" #include <stack> #include <queue> #ifndef RECU #warning("RECU is not defined") /** *前序遍历(根左右) * *1.当前节点为

数据结构二叉树的递归与非递归遍历之 实现可编译(1)java

前一段时间,学习数据结构的各种算法,概念不难理解,只是被C++的指针给弄的犯糊涂,于是用java,web,javascript,分别去实现数据结构的各种算法. 二叉树的遍历,本分享只是以二叉树中的先序遍历为例进行说明,中序遍历和后序遍历,以此类推! 二叉树递归与非递归遍历的区别,虽然递归遍历,跟容易读懂,代码量少,运算快,但是却容易出现溢出的问题,所以所以非递归遍历,在处理千万级的运算量时会先的很有用处. 二叉树的先序遍历:先访问根节点,再访问先后访问左右节点.如图: 二叉树的递归遍历之java

二叉树的遍历和线索二叉树

二叉树的遍历和线索二叉树 递归遍历 先序遍历 void PreOrder(BiTree T){ if(T != NULL){ visit(T); PreOrder(T->lchild); PreOrder(T-rchild); } } 中序遍历 void InOrder(BiTree T){ if(T != NULL){ InOrder(T->lchild); visit(T); InOrder(T->rchild); } } 后序遍历 void PostOrder(BiTree T){

二叉树的非递归遍历--京东2015笔试回忆

题目回忆: C/C++研发试卷:偏重于数据结构的考察,编程题有2题+1题附加题: 1.输入整数n,求m,m>9,m中各个数位的乘积=n的最小整数;如n=36,m=49; 2.二叉树前序遍历的非递归实现(本文的总结) 3.求第n个数,这个序列满足(2^i)*(3^j)*(5^k),前7个为:2,3,4,5,6,8,10 .... 小题有基本的数据结构.程序运行结果.SQL题目. 4.删除表格用DROP命令,死锁产生的条件: 4.1互斥使用(资源独占) 一个资源每次只能给一个进程使用 4.2.不可强

数据结构——二叉树遍历之“递归与非递归遍历”

简述 二叉树的遍历分为先序遍历.中序遍历和后序遍历.如下图所示: 递归遍历 private void bianli1(List<Integer> list, TreeNode root) { // 先序遍历 if (root == null) { return; } list.add(root.val); bianli1(list, root.left); bianli1(list, root.right); } private void bianli2(List<Integer>

JAVA递归、非递归遍历二叉树(转)

原文链接: JAVA递归.非递归遍历二叉树 import java.util.Stack; import java.util.HashMap; public class BinTree { private char date; private BinTree lchild; private BinTree rchild; public BinTree(char c) { date = c; } // 先序遍历递归 public static void preOrder(BinTree t) {

递归遍历二叉树

递归遍历分三种: 1.前序遍历二叉树(二叉树非空) 1.访问根节点 2.前序遍历左子树 3.前序遍历右子树 2.中序遍历二叉树(二叉树非空) 1.中序遍历左子树 2.访问根节点 3.中序遍历右子树 3.后序遍历二叉树(二叉树非空) 1.后序遍历左子树 2.后序遍历右子树 3.访问根节点 三种递归的算法遍历,终止条件是二叉树为空的时候. 记忆的方法呢,前中后,都是以根节点命名的,前序,先访问根节点,中序,根节点在第二,后序,根节点最后进行访问.