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

歡迎訪問(wèn) 生活随笔!

生活随笔

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

编程问答

数据结构与算法--重建二叉树

發(fā)布時(shí)間:2023/12/4 编程问答 23 豆豆
生活随笔 收集整理的這篇文章主要介紹了 数据结构与算法--重建二叉树 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

二叉樹(shù)

  • 樹(shù)在實(shí)際編程中經(jīng)常遇到地一種數(shù)據(jù)結(jié)構(gòu)。上一篇中我們解釋了二叉樹(shù)及其原理,從中可以知道,樹(shù)地操作會(huì)涉及到很多指針地操作,我們一般遇到地樹(shù)相關(guān)地問(wèn)題差不多都是二叉樹(shù)。二叉樹(shù)最重要地莫過(guò)于遍歷,即按照某一順序訪問(wèn)樹(shù)中所有節(jié)點(diǎn),通常有如下幾種遍歷方式:
    • 前序遍歷:先根節(jié)點(diǎn),左節(jié)點(diǎn),右節(jié)點(diǎn)。用以上順序來(lái)訪問(wèn)
    • 中序遍歷:先左節(jié)點(diǎn),中節(jié)點(diǎn),右節(jié)點(diǎn)
    • 后續(xù)遍歷:先左節(jié)點(diǎn),右節(jié)點(diǎn),中節(jié)點(diǎn)
  • 以上三種遍歷都有遞歸和循環(huán)兩種不同地實(shí)現(xiàn)方式,每一種遍歷地遞歸實(shí)現(xiàn)都比循環(huán)實(shí)現(xiàn)要簡(jiǎn)單。在上一節(jié)中已經(jīng)給出了三種遞歸遍歷地實(shí)現(xiàn)方式。
  • 二叉樹(shù)還有很多特例,二叉搜索樹(shù)左子樹(shù)中節(jié)點(diǎn)總數(shù)小于或者等于根節(jié)點(diǎn)。右子樹(shù)地節(jié)點(diǎn)總數(shù)大于等于根節(jié)點(diǎn)。
  • 二叉樹(shù)特例還包括堆和紅黑樹(shù)。堆分為最大堆和最小堆。
  • 一下我們利用二叉樹(shù)地三種遍歷方式地特性來(lái)解決如下算法問(wèn)題:

重建二叉樹(shù)

  • 題目:輸入某個(gè)二叉樹(shù)前序遍歷,中序遍歷地結(jié)果,請(qǐng)重建該二叉樹(shù)。我們假設(shè)駛?cè)氲厍靶虮闅v,中序遍歷不包含重復(fù)數(shù)字。例如:前序(1,2,4,7,3,5,6,8),中序遍歷(4,7,2,1,5,3,8,6),如下圖
分析
  • 二叉樹(shù)前序遍歷中,第一個(gè)數(shù)字總數(shù)樹(shù)地根節(jié)點(diǎn)。
  • 中序遍歷中,根節(jié)點(diǎn)在序列中間。左子樹(shù)在根節(jié)點(diǎn)左邊,右子樹(shù)在根節(jié)點(diǎn)右邊
  • 我們通過(guò)前序遍歷找到根節(jié)點(diǎn)
  • 在中序遍歷中確認(rèn)跟節(jié)點(diǎn)的位置后得到左右子樹(shù)的長(zhǎng)度
  • 接著將左子樹(shù),右子樹(shù)分別執(zhí)行以上流程(遞歸)
  • 如下圖,在二叉樹(shù)的前序遍歷和中序遍歷的序列中確定根節(jié)點(diǎn)的值,左子樹(shù)的值和右子樹(shù)的值

實(shí)現(xiàn)
  • 以上對(duì)二叉樹(shù)節(jié)點(diǎn)地定義:
/*** 二叉樹(shù)節(jié)點(diǎn)對(duì)象定義** @author liaojiamin* @Date:Created in 15:24 2020/12/11*/ public class BinaryNode implements Comparable {private Object element;private BinaryNode left;private BinaryNode right;/*** 樹(shù)高度*/private int height;private int count;public BinaryNode(Object element, BinaryNode left, BinaryNode right) {this.element = element;this.left = left;this.right = right;this.count = 1;this.height = 0;}public int getHeight() {return height;}public void setHeight(int height) {this.height = height;}public Object getElement() {return element;}public void setElement(Object element) {this.element = element;}public BinaryNode getLeft() {return left;}public void setLeft(BinaryNode left) {this.left = left;}public BinaryNode getRight() {return right;}public void setRight(BinaryNode right) {this.right = right;}public int getCount() {return count;}public void setCount(int count) {this.count = count;}@Overridepublic int compareTo(Object o) {if (o == null) {return 1;}int flag;if (o instanceof Integer) {int myElement = (int) this.element - (int) o;flag = myElement > 0 ? 1 : myElement == 0 ? 0 : -1;} else {flag = this.element.toString().compareTo(o.toString());}if (flag == 0) {return 0;} else if (flag > 0) {return 1;} else {return -1;}} }
  • 重構(gòu)二叉樹(shù)實(shí)現(xiàn)
package com.ljm.resource.math.binary;/*** 已知前序遍歷:1,2,4,7,3,5,6,8 中序遍歷:4,7,2,1,5,3,8,6 重建二叉樹(shù)* @author liaojiamin* @Date:Created in 17:22 2021/3/8*/ public class RebuildBinary {public static BinaryNode construct(int[] preOrder, int[] inOrder){if(preOrder == null || inOrder == null || preOrder.length != inOrder.length || preOrder.length <= 0){System.out.println("Invalid input");return null;}return constructCore(preOrder, inOrder, 0, preOrder.length -1, 0, inOrder.length -1);}public static BinaryNode constructCore(int[] preOrder, int[] inOrder,int preStart, int preEnd,int inStart, int inEnd){int rootValue = preOrder[preStart];BinaryNode rootNode = new BinaryNode(rootValue, null, null);//整棵樹(shù)只有一個(gè)root節(jié)點(diǎn)的清空if(preStart == preEnd){if(inStart == inEnd && preOrder[preStart] == inOrder[inStart]){return rootNode;}else {System.out.println("Invalid input");return null;}}//找到root節(jié)點(diǎn)在 中序遍歷中位置int rootInOrderIndex = inStart;while (rootInOrderIndex <= inEnd && inOrder[rootInOrderIndex] != rootValue){rootInOrderIndex ++;}//中序遍歷中沒(méi)有找到root節(jié)點(diǎn)if(rootInOrderIndex == inEnd && inOrder[rootInOrderIndex] != rootValue){System.out.println("Invalid input");return null;}int leftLength = rootInOrderIndex - inStart;//沒(méi)有左子樹(shù)情況start = endif(leftLength > 0){int leftInOrderStart = inStart;int leftInOrderEnd = inStart + leftLength - 1;int leftPreOrderStart = preStart + 1;int leftPreOrderEnd = preStart + leftLength;rootNode.setLeft(constructCore(preOrder, inOrder, leftPreOrderStart, leftPreOrderEnd, leftInOrderStart, leftInOrderEnd));}//存在右節(jié)點(diǎn)if(leftLength < preEnd - preStart){int rightInOrderStart = rootInOrderIndex + 1;int rightInOrderEnd = inEnd;int rightPreOrderStart = preStart + 1 + leftLength;int rightPreOrderEnd = preEnd;rootNode.setRight(constructCore(preOrder, inOrder, rightPreOrderStart, rightPreOrderEnd, rightInOrderStart, rightInOrderEnd));}return rootNode;}public static void main(String[] args) {int preOrder[] = {1,2,4,7,3,5,6,8};int inOrder[] = {4,7,2,1,5,3,8,6};BinaryNode binaryNode = construct(preOrder, inOrder);PostfixExTOTreeEx.printMiddleFirstTree(binaryNode);} }
  • 以上我們?cè)诤瘮?shù)constructCore中,我們先根據(jù)前序遍歷序列地第一個(gè)數(shù)字,創(chuàng)建根節(jié)點(diǎn)。
  • 接下來(lái)在中序遍歷中找到根節(jié)點(diǎn)位置
  • 這樣就能確定左右子樹(shù)地?cái)?shù)量
  • 在前序遍歷和中序遍歷地序列中劃分左右子樹(shù)節(jié)點(diǎn)后,
  • 將左右子樹(shù)遞歸調(diào)用函數(shù)constructCore,分別構(gòu)建左右子樹(shù)。得到最終地樹(shù)

上一篇:數(shù)據(jù)結(jié)構(gòu)與算法–二叉樹(shù)實(shí)現(xiàn)原理
下一篇:數(shù)據(jù)結(jié)構(gòu)與算法–二叉查找樹(shù)實(shí)現(xiàn)原理

總結(jié)

以上是生活随笔為你收集整理的数据结构与算法--重建二叉树的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

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