二叉树的四种遍历方式
二叉樹的四種遍歷方式:
- 二叉樹的遍歷(traversing binary tree)是指從根結(jié)點出發(fā),按照某種次序依次訪問二叉樹中所有的結(jié)點,使得每個結(jié)點被訪問依次且僅被訪問一次。
四種遍歷方式分別為:先序遍歷、中序遍歷、后序遍歷、層序遍歷。
遍歷之前,我們首先介紹一下,如何創(chuàng)建一個二叉樹,在這里用的是先建左樹在建右樹的方法,
首先要聲明結(jié)點TreeNode類,代碼如下:
public class TreeNode {public int data;public TreeNode leftChild;public TreeNode rightChild;public TreeNode(int data){this.data = data;}}再來創(chuàng)建一顆二叉樹:
/*** 構(gòu)建二叉樹* @param list 輸入序列* @return*/public static TreeNode createBinaryTree(LinkedList<Integer> list){TreeNode node = null;if(list == null || list.isEmpty()){return null;}Integer data = list.removeFirst();if(data!=null){node = new TreeNode(data);node.leftChild = createBinaryTree(list);node.rightChild = createBinaryTree(list);}return node;}接下來按照上面列的順序一一講解,
首先來看前序遍歷,所謂的前序遍歷就是先訪問根節(jié)點,再訪問左節(jié)點,最后訪問右節(jié)點,
如上圖所示,前序遍歷結(jié)果為:ABDFECGHI
實現(xiàn)代碼如下:
/*** 二叉樹前序遍歷 根-> 左-> 右* @param node 二叉樹節(jié)點*/public static void preOrderTraveral(TreeNode node){if(node == null){return;}System.out.print(node.data+" ");preOrderTraveral(node.leftChild);preOrderTraveral(node.rightChild);}再者就是中序遍歷,所謂的中序遍歷就是先訪問左節(jié)點,再訪問根節(jié)點,最后訪問右節(jié)點,
如上圖所示,中序遍歷結(jié)果為:DBEFAGHCI
實現(xiàn)代碼如下:
/*** 二叉樹中序遍歷 左-> 根-> 右* @param node 二叉樹節(jié)點*/public static void inOrderTraveral(TreeNode node){if(node == null){return;}inOrderTraveral(node.leftChild);System.out.print(node.data+" ");inOrderTraveral(node.rightChild);}最后就是后序遍歷,所謂的后序遍歷就是先訪問左節(jié)點,再訪問右節(jié)點,最后訪問根節(jié)點。
如上圖所示,后序遍歷結(jié)果為:DEFBHGICA
實現(xiàn)代碼如下:
/*** 二叉樹后序遍歷 左-> 右-> 根* @param node 二叉樹節(jié)點*/public static void postOrderTraveral(TreeNode node){if(node == null){return;}postOrderTraveral(node.leftChild);postOrderTraveral(node.rightChild);System.out.print(node.data+" ");}講完上面三種遞歸的方法,下面再給大家講講非遞歸是如何實現(xiàn)前中后序遍歷的
還是一樣,先看非遞歸前序遍歷
實現(xiàn)代碼如下:
public static void preOrderTraveralWithStack(TreeNode node){Stack<TreeNode> stack = new Stack<TreeNode>();TreeNode treeNode = node;while(treeNode!=null || !stack.isEmpty()){//迭代訪問節(jié)點的左孩子,并入棧while(treeNode != null){System.out.print(treeNode.data+" ");stack.push(treeNode);treeNode = treeNode.leftChild;}//如果節(jié)點沒有左孩子,則彈出棧頂節(jié)點,訪問節(jié)點右孩子if(!stack.isEmpty()){treeNode = stack.pop();treeNode = treeNode.rightChild;}}}中序遍歷非遞歸,在此不過多敘述具體步驟了,
具體過程:
后序遍歷非遞歸實現(xiàn),后序遍歷這里較前兩者實現(xiàn)復(fù)雜一點,我們需要一個標記位來記憶我們此時節(jié)點上一個節(jié)點,具體看代碼注釋
public static void postOrderTraveralWithStack(TreeNode node){Stack<TreeNode> stack = new Stack<TreeNode>();TreeNode treeNode = node;TreeNode lastVisit = null; //標記每次遍歷最后一次訪問的節(jié)點while(treeNode!=null || !stack.isEmpty()){//節(jié)點不為空,結(jié)點入棧,并且指向下一個左孩子while(treeNode!=null){stack.push(treeNode);treeNode = treeNode.leftChild;}//棧不為空if(!stack.isEmpty()){//出棧treeNode = stack.pop();/*** 這塊就是判斷treeNode是否有右孩子,* 如果沒有輸出treeNode.data,讓lastVisit指向treeNode,并讓treeNode為空* 如果有右孩子,將當(dāng)前節(jié)點繼續(xù)入棧,treeNode指向它的右孩子,繼續(xù)重復(fù)循環(huán)*/if(treeNode.rightChild == null || treeNode.rightChild == lastVisit) {System.out.print(treeNode.data + " ");lastVisit = treeNode;treeNode = null;}else{stack.push(treeNode);treeNode = treeNode.rightChild;}}}}最后再給大家介紹一下層序遍歷
具體步驟如下:
實現(xiàn)代碼如下:
public static void levelOrder(TreeNode root){LinkedList<TreeNode> queue = new LinkedList<>();queue.add(root);while(!queue.isEmpty()){root = queue.pop();System.out.print(root.data+" ");if(root.leftChild!=null) queue.add(root.leftChild);if(root.rightChild!=null) queue.add(root.rightChild);}}總結(jié)
以上是生活随笔為你收集整理的二叉树的四种遍历方式的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 150面试题
- 下一篇: 生成式对抗网络Generative Ad