数据结构与算法--二叉树实现原理
生活随笔
收集整理的這篇文章主要介紹了
数据结构与算法--二叉树实现原理
小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.
二叉樹
- 二叉樹(binary tree)是一棵樹,其中每個節(jié)點都不能有多于兩個的子節(jié)點
- 二叉樹的一個性質(zhì)是一顆平均二叉樹的深度要比節(jié)點個數(shù)N小得多(重點),對二叉樹的分析得出其平均深度為O(N\sqrt NN?),而對于特殊類型的二叉樹,即二叉查找樹(binary search tree)其深度的平均值是O(logN)。不過極端情況如下案例,深度可以達到N-1;
實現(xiàn)
- 因為一個二叉樹節(jié)點最多有兩個子節(jié)點,所有可以保存直接連接到他們的鏈。樹節(jié)點的聲明在結構上類似雙向鏈表,在聲明中,節(jié)點就是element的信息加上兩個其他節(jié)點的引用(left和right)組成的結構。
- 我們習慣在畫鏈表的時候,使用矩形標識,當我們表達樹的時候用圓圈,并用直線連接,因為他實際上是圖(graph)。當涉及樹的時候,我們也不明顯的畫出null節(jié)點,因為具有N個節(jié)點的每一個二叉樹都需要N+1個null節(jié)點。
- 二叉樹有許多與搜索無關的引用,主要的是編譯器的設計領域。
案例:表達式樹
- 圖中線上一個表達式樹(expression tree)的案例,表達式樹的葉子是操作數(shù),如常數(shù)或者變量名,而其他的節(jié)點是操作符。由于所有操作符都是二元的(+,-,,/),因此這棵樹正好可以被二叉樹標識,雖然這是最簡單情況,當還是可以有可能含有多于兩個的子節(jié)點。一個節(jié)點也有可能只有一個兒子,如具有一目減運算符的情形。我們將通過遞歸計算左子樹和右子樹所得到的的值應用在根處的運算符而計算出表達式書T的值。在本案例中,左子樹的值是無需計算,只有一個節(jié)點1, 右子樹的值(23-4)+5,因此整個表達式是1+2*3-4+5
- 我們通過遞歸經(jīng)過左節(jié)點,中節(jié)點,右節(jié)點的順序打印表達式,這種遍歷方式叫中序遍歷
- 另外一種遍歷策略,遞歸打印左節(jié)點,右節(jié)點,中節(jié)點,輸出為:123*4-5++,這種輸出策略稱為后順遍歷
- 第三種遍歷策略是先打印運算符**(中節(jié)點),然后遞歸打印左子樹右子樹**,得到的結果:+1±*2345 ,這種遍歷方式叫前序遍歷
構造表達式樹
- 我們先給出一種算法將后綴表達式轉表達式樹。我們已經(jīng)有了將中綴表達式轉后綴表達式的算法(見上一篇),因此我們能夠從這兩常見類型的輸入生成表達式樹。這里所描述的方法和后綴求職算法相似(上一篇),流程如下:
- 我們遍歷表達式,如果是符合操作數(shù)(數(shù)字),就建立一個單節(jié)點樹并推入棧
- 如果沒有符合是操作符(運算符),那么將棧中彈出兩個樹T1,T2,(T1先出棧)
- 將運算符,T1,T2 組成一個新的數(shù),改樹根節(jié)點是操作符,右節(jié)點是T1, 左節(jié)點是T2,
- 將新數(shù)重新壓入棧
- 還是按上面的案例(1 2 3 * 4 - 5 + +)
- 動圖展示整個數(shù)構造過程
代碼實現(xiàn)
/*** 后綴表達式 轉表達式樹** @author liaojiamin* @Date:Created in 15:25 2020/12/11*/ public class PostfixExTOTreeEx {public static BinaryNode toTreeEx(String postfixEx) {MyStack<Object> number = new MyStack<>();String[] chars = postfixEx.split(" ");for (String s : chars) {if (s.matches("([1-9]\\d*\\.?\\d*)|(0\\.\\d*[1-9])")) {//數(shù)字number.push(s);}else if (s.matches("(\\*)|(\\/)|(\\+)|(\\-)")) {if (number.size() < 2) {return null;}BinaryNode binaryRight = null;Object right = number.pop();if(right instanceof BinaryNode){binaryRight = (BinaryNode) right;}else {binaryRight = new BinaryNode(right, null, null);}BinaryNode binaryLeft = null;Object left = number.pop();if(left instanceof BinaryNode){binaryLeft = (BinaryNode) left;}else {binaryLeft = new BinaryNode(left, null, null);}number.push(new BinaryNode(s, binaryLeft, binaryRight));}}return (BinaryNode) number.pop();}/*** 中序遍歷* @author: liaojiamin* @date: 18:15 2020/12/11*/public static void printMiddleFirstTree(BinaryNode binaryNode){if(binaryNode == null || binaryNode.getElement() == null){return;}printMiddleFirstTree(binaryNode.getLeft());System.out.print(binaryNode.getElement());printMiddleFirstTree(binaryNode.getRight());}/*** 前序遍歷* @author: liaojiamin* @date: 18:15 2020/12/11*/public static void printLeftFirstTree(BinaryNode binaryNode){if(binaryNode == null || binaryNode.getElement() == null){return;}System.out.print(binaryNode.getElement());printLeftFirstTree(binaryNode.getLeft());printLeftFirstTree(binaryNode.getRight());}/*** 后序遍歷* @author: liaojiamin* @date: 18:15 2020/12/11*/public static void printRightFirstTree(BinaryNode binaryNode){if(binaryNode == null || binaryNode.getElement() == null){return;}printRightFirstTree(binaryNode.getLeft());printRightFirstTree(binaryNode.getRight());System.out.print(binaryNode.getElement());}public static void main(String[] args) {BinaryNode binaryNode = toTreeEx("1 2 3 * 4 - 5 + +");printMiddleFirstTree(binaryNode);System.out.println();printLeftFirstTree(binaryNode);System.out.println();printRightFirstTree(binaryNode);}}上一篇:數(shù)據(jù)結構與算法–鏈表實現(xiàn)以及應用
下一篇:數(shù)據(jù)結構與算法–重建二叉樹
總結
以上是生活随笔為你收集整理的数据结构与算法--二叉树实现原理的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 最实用的CJK汉字拼音表
- 下一篇: 数据结构与算法--二叉查找树实现原理