亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 編程 > Java > 正文

java使用遞歸,非遞歸方式實現二叉樹的三種常見遍歷方式

2019-11-06 06:15:55
字體:
來源:轉載
供稿:網友

二叉樹的定義:
二叉樹(binary tree)是結點的有限集合,這個集合或者空,或者由一個根及兩個互不相交的稱為這個根的左子樹或右子樹構成.   從定義可以看出,二叉樹包括:1.空樹 2.只有一個根節點 3.只有左子樹   4.只有右子樹  5.左右子樹都存在    有且僅有這5中表現形式    

 二叉樹的特點:

性質1:在二叉樹的第i層上至多有2^(i-1)個節點(i >= 1)性質2:深度為k的二叉樹至多有2^(k-1)個節點(k >=1)性質3:對于任意一棵二叉樹T而言,其葉子節點數目為N0,度為2的節點數目為N2,則有N0 = N2 + 1。性質4:具有n個節點的完全二叉樹的深度 。

二叉樹的遍歷

二叉樹的遍歷分為三種:前序遍歷 中序遍歷 后序遍歷

前序遍歷:按照“根左右”,先遍歷根節點,再遍歷左子樹 ,再遍歷右子樹中序遍歷:按照“左根右“,先遍歷左子樹,再遍歷根節點,最后遍歷右子樹后續遍歷:按照“左右根”,先遍歷左子樹,再遍歷右子樹,最后遍歷根節點 其中前,后,中指的是每次遍歷時候的根節點被遍歷的順序 ============

特殊的二叉樹:

      (1)斜樹:顧名思義,斜樹一定是要斜的;所有的結點都只有左子樹的二叉樹叫左斜樹,所有的結點都只有右子樹的二叉樹叫右斜樹;其實,線性表就可以理解為樹的一種特殊的表現形式;

       (2)滿二叉樹:在一棵二叉樹中,如果所有分支結點都存在左子樹和右子樹,并且所有葉子都在同一層上,這樣的二叉樹稱為滿二叉樹;如圖:

         (3)完全二叉樹:對一棵具有n個結點的二叉樹按層序編號,如果編號為i的結點與同樣深度的滿二叉樹中編號為i的結點在二叉樹中位置完全相同,那么這棵二叉樹稱為完全二叉樹;或者這樣理解:在一棵二叉樹中,除最后一層外,若其余層都是滿的,并且最后一層或者是滿的,或者是右邊缺少連續若干個結點,則稱此樹為完全二叉樹;

所以我們可以這樣判斷完全二叉樹:那就是看著樹的示意圖,心中默默給每個結點按照滿二叉樹的結構逐層順序編號,如果編號出現空檔,就說明不是完全二叉樹,否則就是;

二叉樹的實現:同樣,二叉樹也可以通過順序存儲和鏈式存儲來實現;

          二叉樹的順序存儲就是用一維數組存儲二叉樹中的結點,并且結點的存儲位置,也就是數組的下標要能體現結點之間的邏輯關系,比如父結點與子結點的邏輯關系,子結點 與子結點之間的關系;但順序存儲的實用性不強;

          所以一般采用鏈式存儲;

二叉樹的遍歷:是指從根結點出發,按照某種次序,依次訪問二叉樹中所有結點,使得每個結點被訪問一次且僅被訪問一次;

 二叉樹的遍歷方式有好多種,如果我們限制了從左到右的習慣方式,那么主要就有以下幾種:

         (1)前序遍歷:先訪問子結點,然后前序遍歷左子樹,再前序遍歷右子樹;如下圖,遍歷順序是:ABDGHCEIF

         (2)中序遍歷:從根結點開始(但并不是先訪問根結點),中序遍歷根結點的左子樹,然后方式根結點,最后中序遍歷右樹,如圖,遍歷的順序是:GDHBAEICF

           (3)后序遍歷:從左到右先葉子后結點的方式遍歷訪問左右子樹,最后是訪問根結點;如圖,遍歷的順序是:GHDBIEFCA

          (4)層序遍歷:從樹的第一層,也就是根結點開始訪問,從上而下逐層遍歷,在同一層中,按從左到右的順序對結點進行逐個訪問;如圖,遍歷順序為:ABCDEFGHI

 

二叉樹遍歷的java實現

首先定義二叉樹對象類
package test.tree;public class TreeNode {	public int key;	public String data;	public TreeNode leftChild;	public TreeNode rightChild;	public boolean isVisted=false;  		public TreeNode() {	}			public TreeNode(int key, String data) {		this.key = key;		this.data = data;	}	public TreeNode(int key, String data, TreeNode leftChild,			TreeNode rightChild) {		this.key = key;		this.data = data;		this.leftChild = leftChild;		this.rightChild = rightChild;	}}二叉樹處理遍歷 
package test.tree;import java.util.Stack;public class BinaryTree {	      	    PRivate TreeNode root=null;  	      	    public BinaryTree(){  	        root=new TreeNode(1,"rootNode(A)");  	    }  	      	    /** 	     * 創建一棵二叉樹 	     * <pre> 	     *           A 	     *     B          C 	     *  D     E            F 	     *  </pre> 	     * @param root 	     */  	    public void createBinTree(TreeNode root){  	        TreeNode newNodeB = new TreeNode(2,"B");  	        TreeNode newNodeC = new TreeNode(3,"C");  	        TreeNode newNodeD = new TreeNode(4,"D");  	        TreeNode newNodeE = new TreeNode(5,"E");  	        TreeNode newNodeF = new TreeNode(6,"F");  	        root.leftChild=newNodeB;  	        root.rightChild=newNodeC;  	        root.leftChild.leftChild=newNodeD;  	        root.leftChild.rightChild=newNodeE;  	        root.rightChild.rightChild=newNodeF;  	    }  	      	      	    public boolean isEmpty(){  	        return root==null;  	    }  	  	    //樹的高度  	    public int height(){  	        return height(root);  	    }  	      	    //節點個數  	    public int size(){  	        return size(root);  	    }  	      	      	    private int height(TreeNode subTree){  	        if(subTree==null)  	            return 0;//遞歸結束:空樹高度為0  	        else{  	            int i=height(subTree.leftChild);  	            int j=height(subTree.rightChild);  	            return (i<j)?(j+1):(i+1);  	        }  	    }  	      	    private int size(TreeNode subTree){  	        if(subTree==null){  	            return 0;  	        }else{  	            return 1+size(subTree.leftChild)  	                    +size(subTree.rightChild);  	        }  	    }  	      	    //返回雙親結點  	    public TreeNode parent(TreeNode element){  	        return (root==null|| root==element)?null:parent(root, element);  	    }  	      	    public TreeNode parent(TreeNode subTree,TreeNode element){  	        if(subTree==null)  	            return null;  	        if(subTree.leftChild==element||subTree.rightChild==element)  	            //返回父結點地址  	            return subTree;  	        TreeNode p;  	        //現在左子樹中找,如果左子樹中沒有找到,才到右子樹去找  	        if((p=parent(subTree.leftChild, element))!=null)  	            //遞歸在左子樹中搜索  	            return p;  	        else  	            //遞歸在右子樹中搜索  	            return parent(subTree.rightChild, element);  	    }  	      	    public TreeNode getLeftChildNode(TreeNode element){  	        return (element!=null)?element.leftChild:null;  	    }  	      	    public TreeNode getRightChildNode(TreeNode element){  	        return (element!=null)?element.rightChild:null;  	    }  	      	    public TreeNode getRoot(){  	        return root;  	    }  	      	    //在釋放某個結點時,該結點的左右子樹都已經釋放,  	    //所以應該采用后續遍歷,當訪問某個結點時將該結點的存儲空間釋放  	    public void destroy(TreeNode subTree){  	        //刪除根為subTree的子樹  	        if(subTree!=null){  	            //刪除左子樹  	            destroy(subTree.leftChild);  	            //刪除右子樹  	            destroy(subTree.rightChild);  	            //刪除根結點  	            subTree=null;  	        }  	    }  	      	    public void traverse(TreeNode subTree){  	        System.out.println("key:"+subTree.key+"--name:"+subTree.data);;  	        traverse(subTree.leftChild);  	        traverse(subTree.rightChild);  	    }  	      	    //前序遍歷  	    public void preOrder(TreeNode subTree){ 	        if(subTree!=null){  	            visted(subTree);  	            preOrder(subTree.leftChild);  	            preOrder(subTree.rightChild);  	        }  	    }  	      	    //中序遍歷  	    public void inOrder(TreeNode subTree){  	        if(subTree!=null){  	            inOrder(subTree.leftChild);  	            visted(subTree);  	            inOrder(subTree.rightChild);  	        }  	    }  	      	    //后續遍歷  	    public void postOrder(TreeNode subTree) {  	        if (subTree != null) {  	            postOrder(subTree.leftChild);  	            postOrder(subTree.rightChild);  	            visted(subTree);  	        }  	    }  	      	    //前序遍歷的非遞歸實現  	    public void nonRecPreOrder(TreeNode p){  	        Stack<TreeNode> stack=new Stack<TreeNode>();  	        TreeNode node=p;  	        while(node!=null||stack.size()>0){  	            while(node!=null){  	                visted(node);  	                stack.push(node);  	                node=node.leftChild;  	            }  	            while(stack.size()>0){  	                node=stack.pop();  	                node=node.rightChild;  	            }   	        }  	    }  	      	    //中序遍歷的非遞歸實現  	    public void nonRecInOrder(TreeNode p){  	        Stack<TreeNode> stack =new Stack<TreeNode>();  	        TreeNode node =p;  	        while(node!=null||stack.size()>0){  	            //存在左子樹  	            while(node!=null){  	                stack.push(node);  	                node=node.leftChild;  	            }  	            //棧非空  	            if(stack.size()>0){  	                node=stack.pop();  	                visted(node);  	                node=node.rightChild;  	            }  	        }  	    }  	      	    //后序遍歷的非遞歸實現  	    public void noRecPostOrder(TreeNode p){  	        Stack<TreeNode> stack=new Stack<TreeNode>();  	        TreeNode node =p;  	        while(p!=null){  	            //左子樹入棧  	            for(;p.leftChild!=null;p=p.leftChild){  	                stack.push(p);  	            }  	            //當前結點無右子樹或右子樹已經輸出  	            while(p!=null&&(p.rightChild==null||p.rightChild==node)){  	                visted(p);  	                //紀錄上一個已輸出結點  	                node =p;  	                if(stack.empty())  	                    return;  	                p=stack.pop();  	            }  	            //處理右子樹  	            stack.push(p);  	            p=p.rightChild;  	        }  	    }  	    public void visted(TreeNode subTree){  	        subTree.isVisted=true;  	        System.out.println("key:"+subTree.key+"--name:"+subTree.data);;  	    }  	    	    	    //測試  	    public static void main(String[] args) {  	          	        BinaryTree bt = new BinaryTree();  	        bt.createBinTree(bt.root);  	        System.out.println("the size of the tree is " + bt.size());  	        System.out.println("the height of the tree is " + bt.height());  	          	        System.out.println("*******(前序遍歷)[ABDECF]遍歷*****************");  	        bt.preOrder(bt.root);  	          	        System.out.println("*******(中序遍歷)[DBEACF]遍歷*****************");  	        bt.inOrder(bt.root);  	         	        System.out.println("*******(后序遍歷)[DEBFCA]遍歷*****************");  	        bt.postOrder(bt.root);  	          	        System.out.println("***非遞歸實現****(前序遍歷)[ABDECF]遍歷*****************");  	        bt.nonRecPreOrder(bt.root);  	          	        System.out.println("***非遞歸實現****(中序遍歷)[DBEACF]遍歷*****************");  	        bt.nonRecInOrder(bt.root);  	          	        System.out.println("***非遞歸實現****(后序遍歷)[DEBFCA]遍歷*****************");  	        bt.noRecPostOrder(bt.root);  	    	    } 	    	    }


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
成人性教育视频在线观看| 国产精品99久久久久久www| 欧美一级免费视频| 在线观看国产欧美| 国产精品中文字幕久久久| 一本色道久久综合狠狠躁篇的优点| 欧美性xxxxhd| 欧美尺度大的性做爰视频| 51精品国产黑色丝袜高跟鞋| 91精品国产综合久久久久久蜜臀| 日本中文字幕不卡免费| 精品日本美女福利在线观看| 韩国日本不卡在线| 亚洲国产精品国自产拍av秋霞| 欧美成在线观看| 91爱爱小视频k| 欧美日韩激情视频| 综合网中文字幕| 2019亚洲男人天堂| 在线观看亚洲区| 成人免费视频网| 欧洲永久精品大片ww免费漫画| 国产视频精品自拍| 久久精品国产欧美激情| 日韩一级裸体免费视频| 日本韩国欧美精品大片卡二| 日韩在线免费高清视频| 久久久久久一区二区三区| 国产精品高清免费在线观看| 国产日韩欧美自拍| 日本欧美一级片| 欧美午夜女人视频在线| www.日韩不卡电影av| 欧美大学生性色视频| 国产精品美女久久久久av超清| 午夜免费日韩视频| 欧美日韩国产精品一区二区三区四区| 久久综合九色九九| www.欧美精品| 精品国产一区二区三区久久久狼| 欧美激情一区二区三区久久久| 久久精品国产精品亚洲| 中文字幕无线精品亚洲乱码一区| 欧美成人精品影院| 国产精品入口夜色视频大尺度| www.精品av.com| 精品久久久久久久久久| 欧美日韩国产一区二区三区| 久久亚洲精品国产亚洲老地址| 欧美日韩免费看| 久久99国产精品自在自在app| 国产日本欧美一区二区三区在线| 欧美日韩亚洲一区二区三区| 伊人久久男人天堂| 欧美小视频在线观看| 狠狠躁夜夜躁人人爽超碰91| 欧美在线视频一区二区| 米奇精品一区二区三区在线观看| 亚洲精品国产综合区久久久久久久| 日韩免费在线看| 亚洲欧美一区二区三区在线| 在线观看视频99| 成人免费视频在线观看超级碰| 中文字幕av一区二区| 日韩精品在线第一页| 在线精品国产成人综合| 91成人国产在线观看| 欧美日韩爱爱视频| 久久久这里只有精品视频| 激情成人在线视频| 久久激情视频久久| 国产欧美日韩最新| 日韩美女免费视频| 亚洲电影免费在线观看| 欧美最顶级的aⅴ艳星| 亚洲精品国产综合久久| 国产视频精品一区二区三区| 久久综合久久八八| 欧美色欧美亚洲高清在线视频| 国产精品av免费在线观看| 亚洲精品电影网在线观看| 久久久久这里只有精品| 91牛牛免费视频| 一道本无吗dⅴd在线播放一区| 亚洲二区中文字幕| 亚洲男人天堂2024| 亚洲福利视频免费观看| 国产精品日韩在线播放| 欧美福利视频网站| 91国内在线视频| 亚洲国产另类久久精品| 欧美日韩综合视频| 国产精品美女免费视频| 国产精品久久久久免费a∨大胸| 美日韩丰满少妇在线观看| 亚洲永久免费观看| 日韩欧美在线免费观看| 清纯唯美日韩制服另类| 亚洲精品久久久久国产| 在线观看国产精品淫| 九九热最新视频//这里只有精品| 亚洲第一页在线| 78色国产精品| 国产中文日韩欧美| 欧美在线国产精品| 国模gogo一区二区大胆私拍| 日韩av在线网址| 高清亚洲成在人网站天堂| 97av在线视频免费播放| 久久久国产视频91| 日韩有码在线电影| 国产免费一区视频观看免费| 亚洲摸下面视频| 国产精品视频大全| 国内伊人久久久久久网站视频| 精品国产欧美一区二区五十路| 国产精品久久久久久网站| 欧洲亚洲在线视频| 欧美国产视频日韩| 8x拔播拔播x8国产精品| 国产精品视频99| 国产婷婷成人久久av免费高清| 欧美肥老妇视频| 国产精品黄色av| 久久久在线免费观看| 激情成人在线视频| 亚洲黄页网在线观看| 日本乱人伦a精品| 国产在线拍揄自揄视频不卡99| 国产91精品网站| 日韩亚洲精品视频| 国产精品久久久久久av福利软件| 国产精品678| 亚洲丁香久久久| 欧美老少做受xxxx高潮| 欧美亚洲国产视频小说| 91国产美女在线观看| 国产高清在线不卡| 亚洲精品国产综合区久久久久久久| 亚洲精品456在线播放狼人| 国产欧美va欧美va香蕉在| 日韩精品免费在线| 最新国产精品拍自在线播放| 成人激情视频在线| 国产日韩在线免费| 久久精品免费电影| 欧美成人精品三级在线观看| 精品电影在线观看| 亚洲护士老师的毛茸茸最新章节| 97视频在线观看免费高清完整版在线观看| 92版电视剧仙鹤神针在线观看| 97超碰国产精品女人人人爽| 国产精品日韩专区| 国产精品综合网站| 91精品久久久久久久| 亚洲www永久成人夜色| 国产婷婷97碰碰久久人人蜜臀| 羞羞色国产精品| 亚洲mm色国产网站| 欧美另类xxx| 国产美女精彩久久| 亚洲国产一区二区三区在线观看| 麻豆一区二区在线观看| 国产精品久久久久久中文字|