java二叉樹的非遞歸遍歷
二叉樹的遞歸遍歷比較簡單,這里就不聊了。今天主要聊聊二叉樹的非遞歸遍歷,主要借助于“?!焙筮M先出的特性來保存節(jié)點的順序,先序遍歷和中序遍歷相對來說比較簡單,重點理解后序遍歷。
1. 先看看節(jié)點類型:
//二叉樹的節(jié)點類型 private class Node{ int data; //節(jié)點值 Node leftChild; //左孩子 Node rightChild; //右孩子 public Node(int data) { this.data=data; } }
2.先序遍歷。
非遞歸先序遍歷的思路如下:
1.先將根節(jié)點入棧
2.訪問根節(jié)點
3.如果根節(jié)點存在右孩子,則將右孩子入棧
4.如果根節(jié)點存在左孩子,則將左孩子入棧(注意:一定是右孩子先入棧,然后左孩子入棧)
5.重復2-4
public void preOrder(Node Root) { if(Root==null) { System.out.println("空樹"); return; } Node tmp=Root; Stack<Node> s=new Stack<Node>(); s.push(tmp); //根節(jié)點入棧 while(!s.empty()) { //1.訪問根節(jié)點 Node p=s.pop(); System.out.print(p.data+" "); //2.如果根節(jié)點存在右孩子,則將右孩子入棧 if(p.rightChild!=null) { s.push(p.rightChild); } //3.如果根節(jié)點存在左孩子,則將左孩子入棧 if(p.leftChild!=null) { s.push(p.leftChild); } } System.out.println(); }
3.中序遍歷。
非遞歸中序遍歷的思路如下:
1.先將根節(jié)點入棧
2.將當前節(jié)點的所有左孩子入棧,直到左孩子為空
3.訪問棧頂元素,如果棧頂元素存在右孩子,則繼續(xù)第2步
4.重復第2、3步,直到棧為空并且所有的節(jié)點都被訪問
public void inOrder(Node Root) { if(Root==null) { System.out.println("空樹"); return; } Node tmp=Root; Stack<Node> s=new Stack<Node>(); while(tmp!=null || !s.empty()) { //1.將根節(jié)點入棧 //2.將所有左孩子入棧 while(tmp!=null) { s.push(tmp); tmp=tmp.leftChild; } //3.訪問棧頂元素 tmp=s.pop(); System.out.print(tmp.data+" "); //4.如果棧頂元素存在右孩子,則將右孩子賦值給tmp,也就是將右孩子入棧 if(tmp.rightChild!=null) { tmp=tmp.rightChild; } //否則,將tmp置為null,表示下次要訪問的是棧頂元素 else { tmp=null; } } System.out.println(); }
4.后序遍歷。
后續(xù)遍歷的非遞歸實現(xiàn)思路:
1.根節(jié)點入棧
2.將根節(jié)點的左子樹入棧,直到最左,沒有左孩子為止
3.得到棧頂元素的值,先不訪問,判斷棧頂元素是否存在右孩子,如果存在并且沒有被訪問,則將右孩子入棧,否則,就訪問棧頂元素
public void postOrder(Node Root) { if(Root==null) { System.out.println("空樹"); return; } Node tmp=Root; //當前節(jié)點 Node prev=null; //上一次訪問的節(jié)點 Stack<Node> s=new Stack<Node>(); while(tmp!=null || !s.empty()) { //1.將根節(jié)點及其左孩子入棧 while(tmp!=null) { s.push(tmp); tmp=tmp.leftChild; } if(!s.empty()) { //2.獲取棧頂元素值 tmp=s.peek(); //3.沒有右孩子,或者右孩子已經(jīng)被訪問過 if(tmp.rightChild==null || tmp.rightChild==prev) { //則可以訪問棧頂元素 tmp=s.pop(); System.out.print(tmp.data+" "); //標記上一次訪問的節(jié)點 prev=tmp; tmp=null; } //4.存在沒有被訪問的右孩子 else { tmp=tmp.rightChild; } } } System.out.println(); }
利用非遞歸算法來搜索二叉樹中的某個元素java
層序遍歷
可以利用層序遍歷來解決這個問題
代碼
boolean searchUsingLevelOrder(BinaryTreeNode root,int data){ BinaryTreeNode temp; LLQueue q = new LLQueue(); if(root == null) return false; q.enqueue(root); while(q.isNotEmpty()){ temp = q.deQueue(); if(data == root.getData()) return true; if(temp.getLeft() != null) q.enqueue(temp.getLeft()); if(temp.getRight() != null) q.enqueue(temp.getRight()); } q.deleteQueue(); return false; }
Java遞歸、非遞歸實現(xiàn)二叉樹遍歷
最近找工作做筆試題發(fā)現(xiàn)很重要,就自己寫了一點,和大家分享
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) { if (t == null) { return; } System.out.print(t.date); preOrder(t.lchild); preOrder(t.rchild); } // 中序遍歷遞歸 public static void InOrder(BinTree t) { if (t == null) { return; } InOrder(t.lchild); System.out.print(t.date); InOrder(t.rchild); } // 后序遍歷遞歸 public static void PostOrder(BinTree t) { if (t == null) { return; } PostOrder(t.lchild); PostOrder(t.rchild); System.out.print(t.date); } // 先序遍歷非遞歸 public static void preOrder2(BinTree t) { Stack<BinTree> s = new Stack<BinTree>(); while (t != null || !s.empty()) { while (t != null) { System.out.print(t.date); s.push(t); t = t.lchild; } if (!s.empty()) { t = s.pop(); t = t.rchild; } } } // 中序遍歷非遞歸 public static void InOrder2(BinTree t) { Stack<BinTree> s = new Stack<BinTree>(); while (t != null || !s.empty()) { while (t != null) { s.push(t); t = t.lchild; } if (!s.empty()) { t = s.pop(); System.out.print(t.date); t = t.rchild; } } } // 后序遍歷非遞歸 public static void PostOrder2(BinTree t) { Stack<BinTree> s = new Stack<BinTree>(); Stack<Integer> s2 = new Stack<Integer>(); Integer i = new Integer(1); while (t != null || !s.empty()) { while (t != null) { s.push(t); s2.push(new Integer(0)); t = t.lchild; } while (!s.empty() && s2.peek().equals(i)) { s2.pop(); System.out.print(s.pop().date); } if (!s.empty()) { s2.pop(); s2.push(new Integer(1)); t = s.peek(); t = t.rchild; } } } public static void main(String[] args) { BinTree b1 = new BinTree('a'); BinTree b2 = new BinTree('b'); BinTree b3 = new BinTree('c'); BinTree b4 = new BinTree('d'); BinTree b5 = new BinTree('e'); /** * a * / / * b c * / / * d e */ b1.lchild = b2; b1.rchild = b3; b2.lchild = b4; b2.rchild = b5; BinTree.preOrder(b1); System.out.println(); BinTree.preOrder2(b1); System.out.println(); BinTree.InOrder(b1); System.out.println(); BinTree.InOrder2(b1); System.out.println(); BinTree.PostOrder(b1); System.out.println(); BinTree.PostOrder2(b1); } }
到此這篇關于java二叉樹的非遞歸遍歷的文章就介紹到這了,更多相關java二叉樹內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
揭秘SpringBoot!一分鐘教你實現(xiàn)配置的動態(tài)神刷新
在今天的指南中,我們將深入探索SpringBoot?動態(tài)刷新的強大功能,讓你的應用保持最新鮮的狀態(tài),想象一下,無需重啟,你的應用就能實時更新配置,是不是很酷?跟我一起,讓我們揭開這項技術如何讓開發(fā)變得更加靈活和高效的秘密吧!2024-03-03SpringBoot集成內存數(shù)據(jù)庫H2的實踐
h2是內存數(shù)據(jù)庫,查詢高效,可以在開發(fā)初期使用它。本文主要介紹了SpringBoot集成內存數(shù)據(jù)庫H2的實踐,具有一定的參考價值,感興趣的可以了解一下2021-09-09MyBatis-Plus 如何實現(xiàn)連表查詢的示例代碼
這篇文章主要介紹了MyBatis-Plus 如何實現(xiàn)連表查詢的示例代碼,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧2020-08-08SpringBoot設置首頁(默認頁)跳轉功能的實現(xiàn)方案
這篇文章主要介紹了SpringBoot設置首頁(默認頁)跳轉功能,本文通過兩種方案,給大家介紹的非常詳細,具有一定的參考借鑒價值,需要的朋友可以參考下2019-07-07關于BeanUtils.copyProperties(source, target)的使用
這篇文章主要介紹了關于BeanUtils.copyProperties(source, target)的使用說明,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2021-06-06