日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

二叉树的遍历实现-1(三级)

發(fā)布時間:2024/4/13 编程问答 30 豆豆
生活随笔 收集整理的這篇文章主要介紹了 二叉树的遍历实现-1(三级) 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.
package com.learn.btree;/*** 二叉鏈表的節(jié)點(diǎn)* @author Leon.Sun**/ public class Node {/*** 節(jié)點(diǎn)的值*/// private Object value;Object value;/*** 左孩子* 左子樹的引用* 同樣為了處理方便,我們把private去掉*/// private Node leftChild; Node leftChild;/*** 右子樹的引用*/// private Node rightChild;Node rightChild;public Node() {super();}public Node(Object value) {super();this.value = value;}public Node(Object value, Node leftChild, Node rightChild) {super();this.value = value;this.leftChild = leftChild;this.rightChild = rightChild;}/*** 這個toString該怎么寫呢* 輸出三個屬性的值就可以了*/@Overridepublic String toString() {return "Node [value=" + value + ", leftChild=" + leftChild + ", rightChild=" + rightChild + "]";}} package com.learn.btree;/*** 二叉樹接口* 可以有不同的實(shí)現(xiàn)類,每個類可以使用不同的存儲結(jié)構(gòu),比如順序結(jié)構(gòu)、鏈?zhǔn)浇Y(jié)構(gòu)* 鏈?zhǔn)浇Y(jié)構(gòu)可以是二叉的,也可以是三叉的* @author Leon.Sun**/ public interface BinaryTree {/*** 是否空樹* 你的樹是空的嗎,空是什么意思* 有沒有根節(jié)點(diǎn),有根就不是空的了* @return*/public boolean isEmpty();/*** 樹結(jié)點(diǎn)數(shù)量* 樹里面有幾個節(jié)點(diǎn)* @return*/public int size();/*** 獲取二叉樹的高度* 得到樹的高度* @return*/public int getHeight();/*** 查詢指定值的結(jié)點(diǎn)* 在樹里面去找一個值* 我去找20,要告訴我這里沒有20才可以* @param value* @return*/public Node findKey(int value); // 查找/*** 前序遞歸遍歷* 這三個遍歷要采用遞歸來實(shí)現(xiàn)*/public void preOrderTraverse(); /*** 中序遍歷遞歸操作*/public void inOrderTraverse(); /*** 后序遍歷遞歸操作*/public void postOrderTraverse();/*** 后序遍歷遞歸操作* 這個是重載,一個有參,一個無參* @param node 樹根結(jié)點(diǎn)*/public void postOrderTraverse(Node node); /*** 中序遍歷非遞歸操作* 1)對于任意節(jié)點(diǎn)current,若該節(jié)點(diǎn)不為空則將該節(jié)點(diǎn)壓棧,并將左子樹節(jié)點(diǎn)置為current,重復(fù)此操作,直到current為空。 * 2)若左子樹為空,棧頂節(jié)點(diǎn)出棧,訪問節(jié)點(diǎn)后將該節(jié)點(diǎn)的右子樹置為current* 3) 重復(fù)1、2步操作,直到current為空且棧內(nèi)節(jié)點(diǎn)為空。 */public void inOrderByStack();/*** 前序遍歷非遞歸操作* 1)對于任意節(jié)點(diǎn)current,若該節(jié)點(diǎn)不為空則訪問該節(jié)點(diǎn)后再將節(jié)點(diǎn)壓棧,并將左子樹節(jié)點(diǎn)置為current,重復(fù)此操作,直到current為空。 * 2)若左子樹為空,棧頂節(jié)點(diǎn)出棧,將該節(jié)點(diǎn)的右子樹置為current * 3) 重復(fù)1、2步操作,直到current為空且棧內(nèi)節(jié)點(diǎn)為空。*/public void preOrderByStack(); /*** 后序遍歷非遞歸操作* 1)對于任意節(jié)點(diǎn)current,若該節(jié)點(diǎn)不為空則訪問該節(jié)點(diǎn)后再將節(jié)點(diǎn)壓棧,并將左子樹節(jié)點(diǎn)置為current,重復(fù)此操作,直到current為空。 * 2)若左子樹為空,取棧頂節(jié)點(diǎn)的右子樹,如果右子樹為空或右子樹剛訪問過,則訪問該節(jié)點(diǎn),并將preNode置為該節(jié)點(diǎn) * 3) 重復(fù)1、2步操作,直到current為空且棧內(nèi)節(jié)點(diǎn)為空。 */public void postOrderByStack(); /*** 按照層次遍歷二叉樹* 這個需要借助隊(duì)列來實(shí)現(xiàn),這里還是包含很多技能點(diǎn)的*/public void levelOrderByStack(); } package com.learn.btree;/*** 他要實(shí)現(xiàn)一下2我們的BinaryTree,要實(shí)現(xiàn)這個接口* 你把這些方法掌握了,那二叉樹的基本操作呢就基本上知道了* 但不是所有的操作,基本操作都知道了* 這是一個鏈?zhǔn)蕉鏄涞膶?shí)現(xiàn)類* * 這個類里面我們做一個操作,* @author Leon.Sun**/ public class LinkedBinaryTree implements BinaryTree {/*** 根節(jié)點(diǎn)*/private Node root;/*** 我每次增加一個節(jié)點(diǎn)的時候他就加1* 但是為什么我們目前沒有寫size,* 因?yàn)槟壳皼]有增加的方法,* 我們創(chuàng)建這棵樹,是直接做的,* 當(dāng)然還有簡單的方法,創(chuàng)建這棵樹時候,你把7傳進(jìn)來* 但是這么做也沒有什么技術(shù)含量,這個size我們每次=求就可以了*/// private int size;/*** 然后我們再給他提供一個構(gòu)造方法*/ public LinkedBinaryTree(Node root) {super();this.root = root;}public LinkedBinaryTree() {super();}/*** 這里永遠(yuǎn)返回false,* 怎么樣這棵樹才是空的呢,樹是空的,一個節(jié)點(diǎn)也沒有*/@Overridepublic boolean isEmpty() {/*** 就是root等于null* 如果root等于的話他就是一個空的樹*/return root==null;}/*** 我們的這個size該怎么辦,*/@Overridepublic int size() {System.out.println("二叉樹節(jié)點(diǎn)的個數(shù): ");/*** 你想一下他的數(shù)量應(yīng)該是多少* 你怎么知道他的結(jié)構(gòu)是7呢,* 因?yàn)樽筮吺?,右邊是4,* 整個就是2+4+根1等于7* 你怎么知道這個是4呢,* 左邊是1,右邊是2,再加上根1,等于4* 你怎么知道這個是2呢,* 左邊是0,右邊是1,再加上這個根1,等于2* 你怎么知道7是1呢,* 左邊是0,右邊是0,再加上1等于1* 好像和我們剛才求高度是一樣的* 只不過高度里面是求兩個里面最大的樹* 我們現(xiàn)在是兩個數(shù)相加* */return this.size(root);}/*** 這里還是寫成private不對外公布了* 這里面要寫一個Node,* 寫Node root吧,root可讀性強(qiáng)*/private int size(Node root) {/*** 如果root等于null還是返回0*/if(root==null) { return 0;}else {/*** 獲取左子樹的size*/int nl = this.size(root.leftChild);/*** 獲取右子樹的size*/int nr = this.size(root.rightChild);/*** 返回的是誰,* 返回的是nl+nr+1* 返回左子樹右子樹size只和再加1*/return nl+nr+1; }}/*** 二叉樹的高度*/@Overridepublic int getHeight() {/*** 我們在這里輸出一句話來*/System.out.println("二叉樹的高度是: ");/*** return這個值,* 這個值怎么辦,和剛才一樣提供一個輔助的方法*/return this.getHeight(root);}/*** 提供一個輔助的方法* 這邊傳入一個Node root* @param root* @return*/private int getHeight(Node root) {/*** 首先是有前提條件的,root不能等于null* 如果root不等于null我們就做這個事了*/if(root==null) { /*** 如果root等于null了* 那就return o唄* 遞歸要有一個結(jié)束條件*/return 0;}else {/*** 獲取左子樹的高度* * 得到一個值,* 這里是l不是1,*/int nl = this.getHeight(root.leftChild);/*** 獲取右子樹的高度*/int nr = this.getHeight(root.rightChild);/*** 返回誰,返回左子樹,右子樹較大高度并加1* * 最后返回誰* 如果nl大于nr就返回nl加1* 如果nl小于nr就返回nr加1* 你看又是遞歸,也不怎么復(fù)雜*/return nl>nr ? nl+1 : nr+1; }}@Overridepublic Node findKey(int value) {return null;}/*** 先序 遍歷分幾步,分三步*/@Overridepublic void preOrderTraverse() {/*** 輸出根節(jié)點(diǎn)的值* 我們只要value的值1,* 這樣1就出來了* 這是有條件的,如果root要是等于空呢,* 空節(jié)點(diǎn)你就別輸出了,這也算遞歸的一個結(jié)構(gòu)條件* * 我們只要簡單的變一下就可以了,把這里的ln去了*/if(root!=null) { System.out.print(root.value + " ");/*** 對左子樹進(jìn)行先序遍歷* 左邊玩不了就不會走右邊* * 對做子樹進(jìn)行遍歷怎么辦* 這跟左也沒有關(guān)系啊,* * 如果root不等于null,創(chuàng)建做子樹* */if(root.leftChild!=null) {/*** 創(chuàng)建左子樹,左子樹本來就是存在的* 對做子樹進(jìn)行先序遍歷* 構(gòu)建一個二叉樹,根是左子樹的根* 拿著root.leftChild做根*/BinaryTree leftTree = new LinkedBinaryTree(root.leftChild);/*** 拿著左子樹,4做根,* 這是一顆二叉樹了,對它進(jìn)行遍歷* 對root.leftChild進(jìn)行遍歷* 對左子樹進(jìn)行先序遍歷*/leftTree.preOrderTraverse();}/*** 對右子樹進(jìn)行先序遍歷* 只要這三步就可以* * preOrderTraverse這跟右子樹也沒有關(guān)系,* 什么左子樹什么右子樹,this是當(dāng)前這棵樹* 他找的是當(dāng)前這棵樹,當(dāng)前這棵樹是誰啊,* 就是btree,你這么來做的話可能會死循環(huán)了,* * 但是你這么寫的話代碼有點(diǎn)繁瑣,條件都是一樣的,*/if(root.rightChild!=null) {BinaryTree rightTree = new LinkedBinaryTree(root.rightChild);rightTree.preOrderTraverse();}}}/*** 這里面怎么辦,*/@Overridepublic void inOrderTraverse() {/*** 再調(diào)用一個方法,不管別的我先輸出一個中序遍歷*/System.out.println("中序遍歷");/*** 第一次調(diào)用的時候是不是需要把整個二叉樹的根傳進(jìn)去* 是不是有參數(shù)的,它是對整個樹進(jìn)行二叉遍歷的*/this.inOrderTraverse(root);/*** 輸出換行*/System.out.println();}/*** 我們拿過來復(fù)制一下,這個方法是輔助的* 可以不對外開發(fā),直接寫成private* 傳一個Node root* 這個是不是有根啊* * 我再提供一個輔助的方法,還要傳參* 開發(fā)者考慮這些就可以了,然后再遞歸調(diào)用* 說來說去還要看結(jié)果的運(yùn)行,* 別到時運(yùn)行結(jié)果是錯的那就不好了*/private void inOrderTraverse(Node root) {/*** 再調(diào)用一個方法* 如果root不等于null做三件事* * 三條語句加一個判斷,就可以了* 是不是都用到了遞歸,我們體會到遞歸的強(qiáng)大之處*/if(root!=null) { /*** 遍歷左子樹* 怎么遍歷左子樹,這里面本來就有參數(shù)* * 你知道你調(diào)用inOrderTraverse(root.leftChild)* 這句話意味著什么嗎,剛開始root傳的是誰,傳的是1,* 下一份傳的是誰啊,相當(dāng)于拿著4作為根了去遍歷一下* 遞歸要用了,調(diào)了好多次了,到了葉子的時候還要調(diào),當(dāng)我你們拿到7做根的時候* 拿到node7做根了,如果我拿到node7做根,傳了node7葉子節(jié)點(diǎn)* node7不等于空,所以對他的左子樹進(jìn)行遍歷,左子樹這個時候已經(jīng)是null了* */if(root.leftChild!=null) { this.inOrderTraverse(root.leftChild);}/*** 輸出根的值* 輸出他的值,他的值是7*/System.out.print(root.value + " ");/*** 遍歷右子樹,右子樹也是null了,*/if(root.rightChild!=null) {this.inOrderTraverse(root.rightChild);}}}@Overridepublic void postOrderTraverse() {/*** 輸出一下后序遍歷*/System.out.println("后序遍歷");/*** 第一次調(diào)用是root的根*/this.postOrderTraverse(root);/*** 輸出玩之后再來一個換行*/System.out.println();}/*** 我們再提供一個輔助的方法,這個輔助方法可以不對外面的調(diào)用者開發(fā)* 這里面要傳一個參數(shù),但是這個root是誰不確定,這個方法本來就有了* 有了我就直接用它了*/@Overridepublic void postOrderTraverse(Node node) {/*** 如果node等于null,* * 這里不是root了,而是node了,*/if(node!=null) {/*** 后序遍歷該怎么辦* 遍歷左子樹*/if(node.leftChild!=null) {/*** 左孩子當(dāng)做一個棵樹來遍歷*/this.postOrderTraverse(node.leftChild);}/*** 遍歷右子樹*/if(node.rightChild!=null) {this.postOrderTraverse(node.rightChild);}/*** 輸出根的值* 先寫這一個* 不加ln,加個空格*/System.out.print(node.value + " "); }}@Overridepublic void inOrderByStack() {}@Overridepublic void preOrderByStack() {}@Overridepublic void postOrderByStack() {}@Overridepublic void levelOrderByStack() {}} package com.learn.btree;/*** 在這個測試類里面我們要干什么,* 這是一個測試類,我們按照這些功能依次來實(shí)現(xiàn)* @author Leon.Sun**/ public class Test {public static void main(String[] args) {/*** 你想進(jìn)行遍歷,我想遍歷一下這個數(shù)* 我想看看這個數(shù)一共有幾層,前提是創(chuàng)建一個二叉樹* 怎么來創(chuàng)建一個二叉樹呢,就把這個二叉樹創(chuàng)建起來,* 那該怎么辦呢,一個節(jié)點(diǎn)一個節(jié)點(diǎn)的創(chuàng)建出來,然后指明他們的關(guān)系不就可以了嗎* 從葉子開始吧,從5開始,Node5是不是有構(gòu)造方法,告訴我他的值是多少* 值是5,左右都沒有,這是5了,*/Node node5 = new Node(5,null,null);/*** 再來創(chuàng)建一個4唄* 值是多少,值是4,左孩子沒有,右孩子是node5* 是不是指向他啊,這么久成了*/Node node4 = new Node(4,null,node5);/*** node3也是葉子節(jié)點(diǎn)*/Node node3 = new Node(3,null,null);/*** 下面從7開始吧* 7是葉子節(jié)點(diǎn),那左右都是null* 值是7*/ // Node node7 = new Node(7,null,null);/*** node6,值是6,左孩子沒有,右孩子是node7*/ // Node node6 = new Node(6,null,node7);/*** node6就變成葉子了*/Node node6 = new Node(6,null,null);/*** 2還沒有呢,怎么辦,* node2值是2,左是node3,右是node6*/Node node2 = new Node(2,node3,node6);/*** 最后還差一個node1,值是1* 左邊指向的是node4,右邊指向的是node2* 我們相當(dāng)于把一棵樹給搭建好了* 但是搭建好了之后和LinkedBinargyTree沒有一點(diǎn)關(guān)系* 好像只是把這些節(jié)點(diǎn)按照一定的規(guī)則排到一起了,你下邊還要做一件事* 這棵樹你得知道根是誰,只要我們能夠找到根,基本上就可以找到別的節(jié)點(diǎn)*/Node node1 = new Node(1,node4,node2);/*** 怎么把我們搭建的一大堆變成一棵樹呢,跟我們的類發(fā)生關(guān)聯(lián)* BinaryTree接口,把node1傳進(jìn)去* 這么一棵樹就搭建好了,這個也太沒有技術(shù)含量了吧* 如果有100個節(jié)點(diǎn)的話,我們要加100棵樹嗎,* 因?yàn)槲覀冞@棵樹是沒有特點(diǎn)的,他沒有說左邊的小右邊的大* 值是不是沒有規(guī)律的,比如我們學(xué)過集合了,是不是學(xué)過TreeSet,* 人家里面的樹都是有序的,左邊的永遠(yuǎn)小于根,根永遠(yuǎn)小于右邊的,* 人家都是遞歸定義的,這種情況下你隨便給個值,不需要我們拼接這個數(shù)* 這個大家知道,*/BinaryTree btree = new LinkedBinaryTree(node1);/*** 比如我們把這個語句復(fù)制一份,我這里沒有傳這個根過去* 是不是空的二叉樹一個節(jié)點(diǎn)也沒有,他就是一顆空數(shù)組* 二叉樹我們已經(jīng)實(shí)現(xiàn)兩個操作了,創(chuàng)建二叉樹沒有多大含量* * 我們試一個特殊的情況,這什么意思啊* 創(chuàng)建了一個二叉樹,他是一個空的* 那他的節(jié)點(diǎn)數(shù)量是0,所以我們有時候?qū)懘a的時候要健壯* 某些邊界值一定要考慮到,看我們的代碼是不是完善* 這是0的,*/ // BinaryTree btree = new LinkedBinaryTree();/*** 判斷二叉樹是否為空,這個簡單* 判斷二叉樹是否為空這個怎么辦,輸出一下唄*/System.out.println(btree.isEmpty());System.out.println("先序遍歷:");/*** 先序遍歷遞歸* 什么叫先序遍歷,preOrderTraverse這個就是先序遍歷* 先序遍歷的結(jié)果是多少,1452367* * 但是還是不滿意,main方法是調(diào)用者來寫的,* 能不能我就調(diào)用一個方法,你把所有的事情都給我做了* 這是增加測試者的負(fù)擔(dān),還要創(chuàng)建一個左子樹和右子樹,* 分別進(jìn)行遍歷,我們針對這個做一些改進(jìn),*/btree.preOrderTraverse();System.out.println();System.out.println("中序遍歷:");/*** 中序遍歷遞歸* 中序遍歷的結(jié)果是這個:4513267* 結(jié)果必須對,中序遍歷你只需要做一件事* 這一句話就夠了,有人說你這一句話不太對* 因?yàn)槟氵@里也沒有傳任何值* * 外層不需要傳任何的參數(shù),調(diào)這個方法就可以了,* 所有的細(xì)節(jié)在這里都可以搞定,*/btree.inOrderTraverse();/*** 后序遍歷遞歸* 后序遍歷:5437621* * 到這里我們就把先序中序后序遍歷都給寫出來了* 剛開始怎么辦,剛開始我們寫了一個比較復(fù)雜的,* */btree.postOrderTraverse();/*** 中序遍歷非遞歸* 中序遍歷如果采用非遞歸的遍歷* 需要借助棧* * 我們再實(shí)現(xiàn)一個功能,這個非遞歸的我們先等一等吧* 我們先看一下別的*//*** 按照層次遍歷,借助隊(duì)列* 先把這些層次記住*//*** 在二叉樹中查找某個值*//*** 二叉樹的高度,他總共有幾層* * 二叉樹的高度是幾啊你覺得,* 我要得到這棵樹的高度,這個該怎么寫* 這棵樹的高度是4,4層,我怎么知道這棵樹的高度是4* 要用遞歸,這和遞歸有關(guān)系嗎,遞歸,樹的高度就這么來* 整棵樹的高度是4,我怎么知道是4,先看他左子樹的高度是幾* 目前是2,左子樹是兩層,是2,右子樹的高度是幾,是3,* 左子樹的高度是2,右子樹的高度是3,從里面選一個大的,是3* 別忘了,還有一個根呢,根是幾,根是1,3+1=4* 有人說你怎么知道右子樹是3,左子樹這個是1,這個高度是2* 左子樹是1,右子樹是2,兩個里面找一個大的是幾,是2* 再加上這個根加1,是不是等于3,這好像還是遞歸,* 你怎么知道67這棵樹的高度是2呢,因?yàn)樽笞訕涫?,右子樹是1* 一個0一個1,1再加上這個根,2就是這么得到的,* 你怎么知道7的高度是1,因?yàn)樗淖笞訕涫?,右子樹是0* 兩個最大的是0,再加上個根,等于1,遞歸* 首先大家要有這個思想,因?yàn)闃涞亩x本來就是遞歸的,* 所以解決問題往遞歸來想,如果這個能夠想清楚,代碼估計(jì)就差不多了* * 二叉樹的高度是4,是4吧,怎么不是4,把7去了就變成3* 我們把7去一下,那就變成3了,如果出來個3就差不多了* */System.out.println(btree.getHeight());/*** 二叉樹的節(jié)點(diǎn)數(shù)量* 把我們要實(shí)現(xiàn)二叉樹的框架,都給大家搭建出來了* * 返回二叉樹的節(jié)點(diǎn)數(shù)量,他用了多少個節(jié)點(diǎn)* 節(jié)點(diǎn)數(shù)量輸出一下,這里面我們有一個方法,* 我完全可以這么來寫* * 二叉樹的節(jié)點(diǎn)數(shù)是7個*/System.out.println(btree.size());}}

?

總結(jié)

以上是生活随笔為你收集整理的二叉树的遍历实现-1(三级)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。