二叉樹的廣度優先遍歷、深度優先遍歷的遞歸和非遞歸實現方式

 

二叉樹的遍歷方式:

java

一、深度優先:遞歸,非遞歸實現方式node

  1)先序遍歷:先訪問根節點,再依次訪問左子樹和右子樹post

  2)中序遍歷:先訪問左子樹,再訪問根節點嗎,最後訪問右子樹this

  3)後序遍歷:先訪問左子樹,再訪問右子樹,最後訪問根節點spa

二、廣度優先code

    按照樹的深度,一層一層的訪問樹的節點blog

  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 }
相關文章
相關標籤/搜索