二叉树的广度优先遍历、深度优先遍历的递归和非递归实现方式

二叉树的遍历方式:

1、深度优先:递归,非递归实现方式

  1)先序遍历:先访问根节点,再依次访问左子树和右子树

  2)中序遍历:先访问左子树,再访问根节点吗,最后访问右子树

  3)后序遍历:先访问左子树,再访问右子树,最后访问根节点

2、广度优先

    按照树的深度,一层一层的访问树的节点

  1 package Solution;
  2
  3 import java.util.LinkedList;
  4 import java.util.Queue;
  5 import java.util.Stack;
  6
  7
  8 public class BinaryTree {
  9
 10     // 二叉树节点
 11     public static class BinaryTreeNode {
 12         int value;
 13         BinaryTreeNode left;
 14         BinaryTreeNode right;
 15
 16         public BinaryTreeNode(int value) {
 17             this.value = value;
 18         }
 19
 20         public BinaryTreeNode(int value, BinaryTreeNode left,
 21                 BinaryTreeNode right) {
 22             super();
 23             this.value = value;
 24             this.left = left;
 25             this.right = right;
 26         }
 27
 28     }
 29
 30     // 访问树的节点
 31     public static void visit(BinaryTreeNode node) {
 32         System.out.println(node.value);
 33     }
 34
 35     /** 递归实现二叉树的先序遍历 */
 36     public static void preOrder(BinaryTreeNode node) {
 37         if (node != null) {
 38             visit(node);
 39             preOrder(node.left);
 40             preOrder(node.right);
 41         }
 42     }
 43
 44     /** 递归实现二叉树的中序遍历 */
 45     public static void inOrder(BinaryTreeNode node) {
 46         if (node != null) {
 47             inOrder(node.left);
 48             visit(node);
 49             inOrder(node.right);
 50         }
 51     }
 52
 53     /** 递归实现二叉树的后序遍历 */
 54     public static void postOrder(BinaryTreeNode node) {
 55         if (node != null) {
 56             postOrder(node.left);
 57             postOrder(node.right);
 58             visit(node);
 59         }
 60     }
 61
 62     /** 非递归实现二叉树的先序遍历 */
 63     public static void iterativePreorder(BinaryTreeNode node) {
 64         Stack<BinaryTreeNode> stack = new Stack<>();
 65         if (node != null) {
 66             stack.push(node);
 67             while (!stack.empty()) {
 68                 node = stack.pop();
 69                 // 先访问节点
 70                 visit(node);
 71                 // 把右子结点压入栈
 72                 if (node.right != null) {
 73                     stack.push(node.right);
 74                 }
 75                 // 把左子结点压入栈
 76                 if (node.left != null) {
 77                     stack.push(node.left);
 78                 }
 79             }
 80         }
 81     }
 82
 83     /** 非递归实现二叉树的中序遍历 */
 84     public static void iterativeInOrder(BinaryTreeNode root) {
 85         Stack<BinaryTreeNode> stack = new Stack<>();
 86         BinaryTreeNode node = root;
 87         while (node != null || stack.size() > 0) {
 88             // 把当前节点的所有左侧子结点压入栈
 89             while (node != null) {
 90                 stack.push(node);
 91                 node = node.left;
 92             }
 93             // 访问节点,处理该节点的右子树
 94             if (stack.size() > 0) {
 95                 node = stack.pop();
 96                 visit(node);
 97                 node = node.right;
 98             }
 99         }
100     }
101
102     /** 非递归使用单栈实现二叉树后序遍历 */
103     public static void iterativePostOrder(BinaryTreeNode root) {
104         Stack<BinaryTreeNode> stack = new Stack<>();
105         BinaryTreeNode node = root;
106         // 访问根节点时判断其右子树是够被访问过
107         BinaryTreeNode preNode = null;
108         while (node != null || stack.size() > 0) {
109             // 把当前节点的左侧节点全部入栈
110             while (node != null) {
111                 stack.push(node);
112                 node = node.left;
113             }
114             if (stack.size() > 0) {
115                 BinaryTreeNode temp = stack.peek().right;
116                 // 一个根节点被访问的前提是:无右子树或右子树已被访问过
117                 if (temp == null || temp == preNode) {
118                     node = stack.pop();
119                     visit(node);
120                     preNode = node;// 记录刚被访问过的节点
121                     node = null;
122                 } else {
123                     // 处理右子树
124                     node = temp;
125                 }
126             }
127         }
128     }
129
130     /** 非递归使用双栈实现二叉树后序遍历 */
131     public static void iterativePostOrderByTwoStacks(BinaryTreeNode root) {
132         Stack<BinaryTreeNode> stack = new Stack<>();
133         Stack<BinaryTreeNode> temp = new Stack<>();
134         BinaryTreeNode node = root;
135         while (node != null || stack.size() > 0) {
136             // 把当前节点和其右侧子结点推入栈
137             while (node != null) {
138                 stack.push(node);
139                 temp.push(node);
140                 node = node.right;
141             }
142             // 处理栈顶节点的左子树
143             if (stack.size() > 0) {
144                 node = stack.pop();
145                 node = node.left;
146             }
147         }
148         while (temp.size() > 0) {
149             node = temp.pop();
150             visit(node);
151         }
152     }
153
154     /** 二叉树广度优先遍历——层序遍历 */
155     public static void layerTraversal(BinaryTreeNode root) {
156         Queue<BinaryTreeNode> queue = new LinkedList<>();
157
158         if (root != null) {
159             queue.add(root);
160             while (!queue.isEmpty()) {
161                 BinaryTreeNode currentNode = queue.poll();
162                 visit(currentNode);
163                 if (currentNode.left != null) {
164                     queue.add(currentNode.left);
165                 }
166
167                 if (currentNode.right != null) {
168                     queue.add(currentNode.right);
169                 }
170
171             }
172         }
173     }
174
175     public static void main(String[] args) {
176
177         // 构造二叉树
178         // 1
179         // / 180         // 2 3
181         // / / 182         // 4 5 7
183         // \ /
184         // 6 8
185         BinaryTreeNode root = new BinaryTreeNode(1);
186         BinaryTreeNode node2 = new BinaryTreeNode(2);
187         BinaryTreeNode node3 = new BinaryTreeNode(3);
188         BinaryTreeNode node4 = new BinaryTreeNode(4);
189         BinaryTreeNode node5 = new BinaryTreeNode(5);
190         BinaryTreeNode node6 = new BinaryTreeNode(6);
191         BinaryTreeNode node7 = new BinaryTreeNode(7);
192         BinaryTreeNode node8 = new BinaryTreeNode(8);
193
194         root.left = node2;
195         root.right = node3;
196         node2.left = node4;
197         node3.left = node5;
198         node3.right = node7;
199         node5.right = node6;
200         node7.left = node8;
201         System.out.println("二叉树先序遍历");
202         preOrder(root);
203         System.out.println("二叉树先序遍历非递归");
204         iterativePreorder(root);
205         System.out.println("二叉树中序遍历");
206         inOrder(root);
207         System.out.println("二叉树中序遍历非递归");
208         iterativeInOrder(root);
209         System.out.println("二叉树后序遍历");
210         postOrder(root);
211         System.out.println("二叉树单栈非递归后序遍历");
212         iterativePostOrder(root);
213         System.out.println("二叉树双栈非递归后序遍历");
214         iterativePostOrderByTwoStacks(root);
215         System.out.println("二叉树层树序遍历");
216         layerTraversal(root);
217     }
218 }
时间: 2024-10-29 19:10:39

二叉树的广度优先遍历、深度优先遍历的递归和非递归实现方式的相关文章

遍历多叉树(递归、非递归广度优先、深度优先)

简单的遍历一个树形结构数据的几种方法.非递归方法效率最好. 1 (function (window, undefined) { 2 var treeNodes = [ 3 { 4 id: 1, 5 name: '1', 6 children: [ 7 { 8 id: 11, 9 name: '11', 10 children: [ 11 { 12 id: 111, 13 name: '111', 14 children:[] 15 }, 16 { 17 id: 112, 18 name: '11

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) {

二叉树(3)----后序遍历,递归和非递归方式

1.二叉树定义 typedef struct BTreeNodeElement_t_ { void *data; } BTreeNodeElement_t; typedef struct BTreeNode_t_ { BTreeNodeElement_t *m_pElemt; struct BTreeNode_t_ *m_pLeft; struct BTreeNode_t_ *m_pRight; } BTreeNode_t; 2.后序遍历 定义: 给定根节点,首先遍历左子树,然后遍历右子树,最后

Java数据结构系列之——树(4):二叉树的中序遍历的递归与非递归实现

package tree.binarytree; import java.util.Stack; /** * 二叉树的中序遍历:递归与非递归实现 * * @author wl * */ public class BiTreeInOrder { // 中序遍历的递归实现 public static void biTreeInOrderByRecursion(BiTreeNode root) { if (root == null) { return; } biTreeInOrderByRecursi

二叉树遍历递归与非递归实现

说明:本文仅供学习交流,转载请标明出处,欢迎转载! 二叉树遍历是二叉树中非常基础的部分,也是学习二叉树必须熟练掌握的部分,下面我们先给出二叉树三种遍历方式的定义,并通过举例来说明二叉树遍历的过程. 二叉树的遍历分为:前序遍历(也叫先序遍历).中序遍历.后序遍历.所谓前.中.后都是根据当前子树根结点相对左右孩子的位置而言,也就是说: 前序遍历:根结点在前,即:根 ----->左------->右: 中序遍历:根结点在中间,即:左------>根------>右: 后序遍历:根结点在最

二叉树三种遍历(递归以及非递归实现)

package com.shiyeqiang.tree; import java.util.Stack; public class BiTree { public static void main(String[] args) { // 首先构造叶子节点 BiTree leafA1 = new BiTree(4); BiTree leafA2 = new BiTree(5); BiTree leafB1 = new BiTree(6); BiTree leafB2 = new BiTree(7)

二叉树遍历算法总结(递归与非递归)

一:前言 二叉树的遍历方法分四种:前序,中序,后序以及层次遍历. 其中,前中后遍历方法的实现分递归和非递归,非递归遍历的实现需要借助于栈. 实际上,递归的调用就是一种栈的实现,所以,非递归遍历就需要人工借助栈结构来实现. 而层次遍历需要借助队列. 二:前中后序遍历 递归遍历: 递归遍历的思想和方法很简单,通过调整输出语句来实现前,中,后三种遍历. 代码如下: 1 void show(BiTree T) 2 { 3 if(T) 4 { 5 printf("%c ",T->data)

二叉树递归与非递归遍历,最近公共父节点算法

#include <iostream> #include <stack> using namespace std; #define MAX 100 //字符串最大长度 typedef struct Node //二叉树结点 { char data; Node *lchild,*rchild; } *Btree; void createBT(Btree &t); //先序构造二叉树 void preorder(Btree &t); //二叉树递归先序遍历 void i

图的遍历---深度优先遍历与广度优先遍历

对下图进行遍历,分别采用深度优先和广度优先 1.深度优先遍历的主要思想:首先从一个未被访问的顶点作为起始顶点,沿当前顶点的边走到未访问过的顶点: 当没有未访问过的顶点时,则回到上一个顶点,继续试探访问别的顶点,直到所有顶点都被访问. 显然,深度优先遍历是沿着图的某一条分支遍历直到末端,然后回溯,再沿着另一条进行同样的遍历,直到所有顶点被访问. /*深度优先搜索算法遍历图的各个顶点*/ #include<stdio.h> int n, sum, book[101]; int e[101][101