Java中用遞迴和迭代實現二叉樹的中序( InOrder )遍歷
與陣列和連結串列不同,二叉樹有幾種遍歷方式。遍歷演算法大致分為深度優先和廣度優先遍歷演算法,這取決於演算法實際如何工作。顧名思義,深度優先在訪問同級別兄弟之前先向二叉樹縱深訪問,而廣度優先是先訪問同一級別中的所有節點然後再進入下一級別,因此它也被稱為級別順序遍歷。 PreOrder和InOrder樹遍歷演算法都是深度優先的,預序和中序演算法之間的唯一區別是訪問二叉樹的根,左節點和右節點的順序。
InOrder遍歷演算法首先訪問左節點,然後是root節點,最後是右節點。這與首先訪問根的預序遍歷不同。InOrder遍歷的一個重要特性是,如果給定的二叉樹是二叉搜尋樹,它將按排序順序列印節點。
請記住,如果左子樹中的所有節點都低於root並且右子樹中的所有節點都大於root,則二叉樹稱為二叉搜尋樹。
在示例中,使用二叉搜尋樹來演示InOrder樹遍歷以排序順序列印二叉樹的節點,並分享了這個問題的遞迴和迭代解決方案。從面試的角度來看,這非常重要。即使遞迴解決方案更容易,佔用更少的程式碼行,並且更具可讀性,您也應該知道如何在沒有Java遞迴的情況下遍歷二叉樹,以便在程式設計面試中做得更好。
Java中InOrder遍歷二叉樹 - 遞迴
由於二叉樹是遞迴資料結構,因此遞迴是解決基於樹的問題的最佳方法。以下是二叉樹InOrder遍歷的步驟:
1)訪問左節點
2)訪問root
3)訪問右節點
要實現此演算法,您可以使用InOrder遍歷編寫一個方法來遍歷二叉樹的所有節點,方法如下:
在inOrder(TreeNode節點)中編寫方法
檢查node == null,如果是,則返回,這是我們的基本情況。
呼叫inOrder(node.left)以遞迴方式訪問左子樹
列印節點的值
呼叫inOrder(node.right)以遞迴方式遍歷右子樹。
這將按照InOrder遍歷列印二叉樹的所有節點。如果二叉樹是二叉搜尋樹,則樹的所有節點將按排序順序列印。這是一種在Java中實現InOrder演算法的方法:
private void inOrder(TreeNode node) { if (node == null) { return; } inOrder(node.left); System.out.printf("%s ", node.data); inOrder(node.right); } |
該方法是私有方法,因為它是透過另一個公共方法inorder()公開的,後者不需要來自客戶端的引數。這是一個facade模式的例子,它使客戶端的方法更簡單。遞迴演算法很容易理解,深入到左子樹,直到找到葉節點。一旦找到,遞迴堆疊就開始展開,列印節點資料並開始探索右子樹。
Java中InOrder遍歷二叉樹 - 迭代
您可以使用堆疊將遞迴的順序演算法轉換為迭代的順序演算法。。 沒有遞迴的解決方案雖然不容易閱讀,但也不是很難理解。 我們從根和程式開始,直到當前節點或Stack不為空。 我們開始從左子樹推節點,直到到達葉節點。 此時,我們pop()最後一個元素,列印它的值,並透過指定current=current.right開始探索右子樹。這將一直持續到堆疊變空為止,此時,二叉樹的所有元素都被訪問,樹遍歷完成。
4 / \ 2 5 / \ \ 1 3 6 public void inOrderWithoutRecursion() { Stack nodes = new Stack<>(); TreeNode current = root; while (!nodes.isEmpty() || current != null) { if (current != null) { nodes.push(current); current = current.left; } else { TreeNode node = nodes.pop(); System.out.printf("%s ", node.data); current = node.right; } } } Output 1 2 3 4 5 6 |
因為我們的二叉樹是一個二叉搜尋樹,所以可以看到它們是按排序順序列印的。
Java中使用InOrder演算法遍歷二叉樹
這是我們在Java中使用InOrder演算法遍歷二叉樹的完整程式。類似於我們之前看到的preOrder示例,唯一的區別是root的訪問順序不是首先而是其次。 遞迴演算法很簡單,但迭代演算法有點難以理解。您必須記住,堆疊是一個後進先出的資料結構,您先推的節點將最後彈出。因為您需要按左--右的順序訪問節點,所以您必須先推左樹的節點,直到到達葉節點。然後列印該值並開始訪問右子樹。
我們使用了相同的BinaryTree和TreeNode類,在早期的基於樹的問題(例如計算葉節點)中,它用於表示二叉樹。二叉樹是常規二叉樹,TreeNode表示二叉樹中的節點。
import java.util.Stack; /* * Java Program to traverse a binary tree * using inorder traversal without recursion. * In InOrder traversal first left node is visited, followed by root * and right node. * * input: * 4 * / \ * 2 5 * / \ \ * 1 3 6 * * output: 1 2 3 4 5 6 */ public class InOrderTraversal { public static void main(String args) throws Exception { // construct the binary tree given in question BinaryTree bt = BinaryTree.create(); // traversing binary tree using InOrder traversal using recursion System.out .println("printing nodes of a binary tree on InOrder using recursion"); bt.inOrder(); System.out.println(); // insert new line // traversing binary tree on InOrder traversal without recursion System.out .println("printing nodes of binary tree on InOrder using iteration"); bt.inOrderWithoutRecursion(); } } class BinaryTree { static class TreeNode { String data; TreeNode left, right; TreeNode(String value) { this.data = value; left = right = null; } boolean isLeaf() { return left == null ? right == null : false; } } // root of binary tree TreeNode root; /** * traverse the binary tree on InOrder traversal algorithm */ public void inOrder() { inOrder(root); } private void inOrder(TreeNode node) { if (node == null) { return; } inOrder(node.left); System.out.printf("%s ", node.data); inOrder(node.right); } public void inOrderWithoutRecursion() { Stack nodes = new Stack<>(); TreeNode current = root; while (!nodes.isEmpty() || current != null) { if (current != null) { nodes.push(current); current = current.left; } else { TreeNode node = nodes.pop(); System.out.printf("%s ", node.data); current = node.right; } } } /** * Java method to create binary tree with test data * * @return a sample binary tree for testing */ public static BinaryTree create() { BinaryTree tree = new BinaryTree(); TreeNode root = new TreeNode("4"); tree.root = root; tree.root.left = new TreeNode("2"); tree.root.left.left = new TreeNode("1"); tree.root.left.right = new TreeNode("3"); tree.root.right = new TreeNode("5"); tree.root.right.right = new TreeNode("6"); return tree; } } Output printing nodes of a binary tree on InOrder using recursion 1 2 3 4 5 6 printing nodes of a binary tree on InOrder using iteration 1 2 3 4 5 6 |
這就是如何使用InOrder遍歷演算法訪問二叉樹的所有節點。 正如我之前所說,InOrder是一種深度優先遍歷演算法,在訪問root之前首先探索左子樹,最後探索右子樹,因此它也被稱為LNR(左節點右)演算法。 inorder遍歷還有一個獨特的屬性,如果給定的二叉樹是二叉搜尋樹,它會按排序順序列印節點。 因此,如果必須按BST的排序順序列印所有節點,則可以使用此演算法。
相關文章
- 遞迴和迭代實現二叉樹先序、中序、後序和層序遍歷遞迴二叉樹
- 遍歷二叉樹的迭代和遞迴方法二叉樹遞迴
- [資料結構]二叉樹的前中後序遍歷(遞迴+迭代實現)資料結構二叉樹遞迴
- 二叉樹迭代器(中序遞迴、前序和後序遍歷)演算法二叉樹遞迴演算法
- 【演算法】二叉樹、N叉樹先序、中序、後序、BFS、DFS遍歷的遞迴和迭代實現記錄(Java版)演算法二叉樹遞迴Java
- 【根據前序和中序遍歷構造二叉樹】棧+迭代 || 遞迴二叉樹遞迴
- 二叉樹的前序、中序、後序的遞迴和迭代實現二叉樹遞迴
- 非遞迴實現先序遍歷和中序遍歷遞迴
- 二叉樹的前中後序遍歷(遞迴和非遞迴版本)二叉樹遞迴
- 什麼是遍歷二叉樹,JavaScript實現二叉樹的遍歷(遞迴,非遞迴)二叉樹JavaScript遞迴
- 非遞迴先序遍歷二叉樹遞迴二叉樹
- 刷題系列 - Python用非遞迴實現二叉樹中序遍歷Python遞迴二叉樹
- 94. 二叉樹的中序遍歷(迭代)二叉樹
- 二叉樹的建立與遍歷(遞迴實現)二叉樹遞迴
- 二叉樹的所有遍歷非遞迴實現二叉樹遞迴
- 遍歷二叉樹的遞迴與非遞迴程式碼實現二叉樹遞迴
- 遍歷二叉樹-------遞迴&非遞迴二叉樹遞迴
- 二叉樹——後序遍歷的遞迴與非遞迴演算法二叉樹遞迴演算法
- python實現二叉樹及其七種遍歷方式(遞迴+非遞迴)Python二叉樹遞迴
- 演算法 -- 實現二叉樹先序,中序和後序遍歷演算法二叉樹
- PHP基於非遞迴演算法實現先序、中序及後序遍歷二叉樹操作示例PHP遞迴演算法二叉樹
- 二叉樹的遍歷 → 不用遞迴,還能遍歷嗎二叉樹遞迴
- 程式碼隨想錄演算法訓練營,9月9日 | 二叉樹遞迴遍歷,迭代遍歷,層序遍歷演算法二叉樹遞迴
- 二叉樹的四種遍歷(遞迴與非遞迴)二叉樹遞迴
- 根據二叉樹的前序遍歷和中序遍歷輸出二叉樹;二叉樹
- 資料結構初階--二叉樹(前中後序遍歷遞迴+非遞迴實現+相關求算結點實現)資料結構二叉樹遞迴
- 二叉樹中序和後序遍歷表示式二叉樹
- 144.二叉樹的前序遍歷145.二叉樹的後序遍歷 94.二叉樹的中序遍歷二叉樹
- 144. 二叉樹的遍歷「前序、中序、後序」 Golang實現二叉樹Golang
- 二叉樹的非遞迴遍歷寫法二叉樹遞迴
- Day14 | 二叉樹遞迴遍歷二叉樹遞迴
- 二叉樹建立後,如何使用遞迴和棧遍歷二叉樹?二叉樹遞迴
- 樹3-二叉樹非遞迴遍歷(棧)二叉樹遞迴
- 106. 從中序與後序遍歷序列構造二叉樹——Java實現二叉樹Java
- 刷題系列 - Python用非遞迴實現二叉樹前序遍歷Python遞迴二叉樹
- 二叉樹的先中後序遍歷二叉樹
- 二叉樹的先,中,後序遍歷二叉樹
- 二叉樹的前中後序遍歷二叉樹