1. 程式人生 > >Java學習筆記-二叉樹的遍歷

Java學習筆記-二叉樹的遍歷

分別採用迭代和棧的方式對二叉樹進行遍歷。


import java.util.LinkedList;

public class MyTree {
    enum Order{
        PREORDER, INORDER, POSTORDER;
    }

    private class Node{
        Integer self;
        Node left;
        Node right;
        int hashCode;
        public Node(Integer i) {
            self = i;
            hashCode = i.intValue();
        }

        public Node(String s) {
            self = new Integer(s);
            hashCode = self.intValue();
        }

        public Node(int i) {
            self = new Integer(i);
            hashCode = self.intValue();
        }

        @Override
        public int hashCode() {
            return hashCode;
        }
    }

    private Node root;
    private int size=0;

    public static void main(String[] args) {
        MyTree tree = new MyTree();
        tree.add(10);
        tree.add(5);
        tree.add(15);
        tree.add(7);
        tree.add(6);
        tree.add(1);
        tree.add(11);
        tree.add(20);
        tree.add(14);
        tree.add(16);
        tree.traversal();

    }

    public void add(int i){
        doAddtoTree(new Node(i));
    }

    public void add(String s){
        doAddtoTree(new Node(s));
    }

    public void add(Integer i){
       doAddtoTree(new Node(i));
       size++;
    }
    
    public int size() {
    	return size;
    }

    public void traversal(){
        doTraversalPreOrder();
        doTraversalMidOrder();
        doTraversalPostOrder();
    }

    private void doAddtoTree(Node node){
        boolean bFound = false;
        Node curNode = root;

        if(addToRoot(node)) return;

        while(!bFound){
            if(curNode.hashCode() > node.hashCode()){
                if (curNode.left != null){
                    curNode = curNode.left;
                }else{
                    curNode.left = node;
                    bFound = true;
                }
            }else if(curNode.hashCode() < node.hashCode()){
                if (curNode.right != null){
                    curNode = curNode.right;
                }else {
                    curNode.right = node;
                    bFound = true;
                }
            }else {
                curNode.self = node.self;
                bFound = true;
            }
        }

    }

    private boolean addToRoot(Node node){
        if (root == null){
            root = node;
            return true;
        }else
            return false;
    }

    private void doTraversalPreOrder(){
        doRecursion(root, Order.PREORDER);
        System.out.println();
        doPreInStack(root, true);
        System.out.println();
    }

    private void doTraversalMidOrder(){
        doRecursion(root, Order.INORDER);
        System.out.println();
        doPreInStack(root, false);
        System.out.println();
    }

    private void doTraversalPostOrder(){
        doRecursion(root, Order.POSTORDER);
        System.out.println();
        doPostStack(root);
        System.out.println();
    }

    /*
        迭代遍歷。前序(PreOrder):先自己(print),再找左子樹(有則迭代),無則再找右子樹(有則迭代,無則返回)
        中序(InOrder):先找左子樹(有則迭代),無則自己(print),再找右子樹(有則迭代,無則返回)
        後序(PostOrder):先找左子樹(有則迭代),無則再找右子樹(有則迭代),無則自己(print)
     */
    private void doRecursion(Node tree, Order ord){
        if (ord == Order.PREORDER) print(tree.self);

        if (tree.left != null){
            doRecursion(tree.left, ord);
        }

        if (ord == Order.INORDER) print(tree.self);

        if (tree.right != null){
            doRecursion(tree.right, ord);
        }
        
        if (ord == Order.POSTORDER) print(tree.self);
    }

    private void doPreInStack(Node tree, boolean bPre){
        LinkedList<Node> stack = new LinkedList<>();

        while((tree != null) || (!stack.isEmpty())){
            while(tree != null){
                stack.push(tree);
                if (bPre) print(tree.self);
                tree = tree.left;
            }

            while((tree==null) && (!stack.isEmpty())){
                tree = stack.pop();
                if (!bPre)print(tree.self);
                tree = tree.right;
            }
        }
    }
    /*
     * 使用棧後序遍歷:
     * 1、根壓棧
     * 2、如果有左孩子,左孩子入棧,如果有右孩子,右孩子入棧,迴圈直到葉子(左右孩子都沒有)
     * 3、葉子出棧(並訪問自己),訪問棧頂(這個葉子的父結點)的右孩子。
     * 3.1、如果有右孩子,重複2~3.
     * 3.2、如果沒有右孩子,繼續出棧。
     * 4、後序遍歷到根節點時棧為空,應結束
     */
    private void doPostStack(Node tree) {
    	Node root = tree;
    	LinkedList<Node> stack = new LinkedList<>();
    	
    	while((tree!=null) || (!stack.isEmpty())) {
    		while(tree!=null) {
    			stack.push(tree);
    			if(tree.left!=null) {
    				tree = tree.left;
    			}else {
    				tree = tree.right;
    			}
    		}
    		while((!stack.isEmpty()) && tree == stack.peek().right) {
    			tree = stack.pop();
    			print(tree.self);
    		}
    		if(!stack.isEmpty()) {
    			tree = stack.peek().right;
    		}else {
    			tree = null;
    		}
    		
    	}
    }

    private void print(Integer i){
        System.out.print(i+" ");
    }
}


前序:10 5 1 7 6 15 11 14 20 16
中序:1 5 6 7 10 11 14 15 16 20
後序:1 6 7 5 14 11 16 20 15 10

相關推薦

Java學習筆記-

分別採用迭代和棧的方式對二叉樹進行遍歷。 import java.util.LinkedList; public class MyTree { enum Order{ PREORDER, INORDER, POSTORDER; }

Java實現簡單

楔子 最近聽了個詞叫紅黑樹,看了下,發現真難。突然覺得自己好失敗。難的不會,寫個簡單的吧。就隨手寫了個二叉樹實現了下遍歷功能,好像比以前只會複製貼上的自己強了點,安慰下自己。 實現樹 二叉樹的組成部分就是節點和關聯關係。Java裡一個節點就是一個類,關聯關

學習筆記--先序、中序、後序、層次的實現(Python)

一、二叉樹類的Python實現及其函式:包括統計結點個數,用遞迴實現的先序遍歷,非遞迴實現的先序遍歷,以及非遞迴實現的後序遍歷。class StackUnderflow(ValueError): pass class SStack(): d

[學習筆記]

n! 後序 左右 學習 pan 就是 -s text 暴力 省選前補一補普及組的知識點 一次考試發現自己不會枚舉所有二叉樹 先序遍歷:根左右 中序遍歷:左根右 後序遍歷:左右根 就是前序遍歷找到每個子樹的根,中序遍歷找到每個子樹的sz。然後遞歸。O(n)復雜度 所

算法(深度優先、廣度優先,前序、中序、後序、層次)及Java實現

order new link left 算法 很多 == 都是 off 二叉樹是一種非常重要的數據結構,很多其它數據結構都是基於二叉樹的基礎演變而來的。對於二叉樹,有深度遍歷和廣度遍歷,深度遍歷有前序、中序以及後序三種遍歷方法,廣度遍歷即我們平常所說的層次遍歷。因為樹的定義

資料結構學習——

1 #include"stdio.h" 2 #include"stdlib.h" 3 #define maxsize 100 4 //二叉樹連結串列型別定義 5 typedef struct node{ 6 char data; 7 struct node

Java面試中最基礎的演算法:氣泡排序演算法和

首先是冒泡需要演算法,氣泡排序是所有的演算法最最基礎的演算法,一般人只是知道思路,但是真正的敲程式碼不一定能敲出來; 氣泡排序玩以後,使得陣列的數安從小到大的順序排列出來; 氣泡排序演算法: public void BuddleSort(){ public st

Java

用java實現二叉樹的遍歷演算法,先編寫二叉樹類BinaryTree,程式碼如下: public class BinaryTree { private int data; //根節點資料

C#

這就是 中序 工作 class stat public 完全 每一個 前期準備 二叉樹遍歷 C# 什麽是二叉樹   二叉樹是每個節點最多有兩個子樹的樹結構  (1)完全二叉樹——若設二叉樹的高度為h,除第 h 層外,其它各層 (1~h-1) 的結

[javaSE] 數據結構-與查找

ngx quest wan ase ngs san http zhong ros %E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A8%8B%E5%BA%8F%E7%9A%84%E6%80%9D%E7%BB%B4%E9%80%BB%E8%BE%91%2018%

非遞歸算法——中序

spa tdi str max logs nor 算法實現 中序遍歷 非遞歸   二叉樹中序遍歷的非遞歸算法同樣可以使用棧來實現,從根結點開始,將根結點的最左結點全部壓棧,當結點p不再有最左結點時,說明結點p沒有左孩子,將該結點 出棧,訪問結點p,然後對其右孩子做同樣的處理

HDU 1710Binary Tree Traversals(已知前序中序,求後序的)

pid http pan clu names pty efi images 樹遍歷 題目鏈接:http://acm.hdu.edu.cn/showproblem.php?pid=1710 解題思路:可以由先序和中序的性質得到 : 先序的第一個借點肯定是當前子樹的根結點, 那

STL實現

nod 數據 blog new friend const turn ace lrn #include<iostream> using namespace std; template<class Type> class BSTree; templat

while nbsp .net right 三種 pos tail stack實現 order 二叉樹遍歷最簡單的就是遞歸了。因為遞歸實質上是棧存了一些中間值,所以我們可以使用stack實現叠代版的遍歷。 中序遍歷 步驟: 首先將root節點作為當前節點。

——篇(c++)

比較 方便 || 遍歷二叉樹 找到 保存 們的 order out 二叉樹——遍歷篇 二叉樹很多算法題都與其遍歷相關,筆者經過大量學習並進行了思考和總結,寫下這篇二叉樹的遍歷篇。 1、二叉樹數據結構及訪問函數 #include <stdio.h> #includ

算法總結

使用 preorder 說明 stack height type pri content 結構圖 ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?

- 和存儲結構

前序遍歷 main inorder esp bottom ive align return c 編程 在《二叉樹的定義和性質》中我們已經認識了二叉樹這種數據結構。我們知道鏈表的每個節點可以有一個後繼,而二叉樹(Binary Tree)的每個節點可以有兩個後繼。比如這樣定義二

(先序、中序、後序)

廣度 nsh 直接 循環 ron color lan 通過 ogr 二叉樹的遍歷(遞歸與非遞歸) 遍歷:traversal  遞歸:recursion 棧----------回溯----------遞歸 棧和回溯有關 本文討論二叉樹的常見遍歷方式的代碼(Java)實現,包括

(王道)

中序 數組 har 不為 位置 mem 一行 遍歷 uil 題目描述: 二叉樹的前序、中序、後序遍歷的定義:前序遍歷:對任一子樹,先訪問跟,然後遍歷其左子樹,最後遍歷其右子樹;中序遍歷:對任一子樹,先遍歷其左子樹,然後訪問根,最後遍歷其右子樹;後序遍歷:對任一子樹,先遍歷其

總結

struct left else oot nor 節點 操作 preorder AC   節點定義如下 1 // Definition for a binary tree node. 2 struct TreeNode { 3 int val; 4 Tre