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

首頁 > 編程 > C > 正文

通過先序遍歷和中序遍歷后的序列還原二叉樹(實現方法)

2020-01-26 14:06:23
字體:
來源:轉載
供稿:網友

當我們有一個

先序遍歷序列:1,3,7,9,5,11

中序遍歷序列:9,7,3,1,5,11

我們可以很輕松的用筆寫出對應的二叉樹。但是用代碼又該如何實現?

下面我們來簡單談談基本思想。

首先,先序遍歷的順序是根據 根-左孩子-右孩子 的順序遍歷的,那么我們可以率先確認的是先序遍歷序列的第一個數就是根節點,然后中序遍歷是根據 左孩子-根-右孩子 的順序遍歷的。我們通過先序遍歷確認了根節點,那么我們只需要在中序遍歷中找到根節點的位置,然后就可以很好地區分出,那些屬于左子樹的節點,那些是屬于右子樹的節點了。如下圖:

我們確定數字1為根節點,然后根據中序遍歷的遍歷順序確定,中序遍歷序列中數字1的左邊全部為左子樹節點,右邊全部為右子樹。通過左子樹節點的個數,得出先序遍歷序列中從根節點往后的連續3個數是屬于左子樹的,剩下的為右子樹。這樣再在左右子樹的序列中重復以上步驟,最終找到沒有子節點為止。

實現代碼如下:

package com.tree.traverse;import java.util.ArrayList;import java.util.List;/** * @author Caijh * * 2017年6月2日 下午7:21:10 */public class BuildTreePreOrderInOrder {  /**    *       1    *       / /   *      3  5    *      /   /   *     7    11   *    /    *   9       */   public static int treeNode = 0;//記錄先序遍歷節點的個數  private List<Node> nodeList = new ArrayList<>();//層次遍歷節點的隊列  public static void main(String[] args) {    BuildTreePreOrderInOrder build = new BuildTreePreOrderInOrder();    int[] preOrder = { 1, 3, 7, 9, 5, 11};    int[] inOrder = { 9, 7, 3, 1, 5, 11};        treeNode = preOrder.length;//初始化二叉樹的節點數    Node root = build.buildTreePreOrderInOrder(preOrder, 0, preOrder.length - 1, inOrder, 0, preOrder.length - 1);    System.out.print("先序遍歷:");    build.preOrder(root);    System.out.print("/n中序遍歷:");    build.inOrder(root);    System.out.print("/n原二叉樹:/n");    build.prototypeTree(root);  }  /**   * 分治法   * 通過先序遍歷結果和中序遍歷結果還原二叉樹   * @param preOrder  先序遍歷結果序列   * @param preOrderBegin   先序遍歷起始位置下標   * @param preOrderEnd  先序遍歷末尾位置下標   * @param inOrder  中序遍歷結果序列   * @param inOrderBegin  中序遍歷起始位置下標   * @param inOrderEnd   中序遍歷末尾位置下標   * @return   */  public Node buildTreePreOrderInOrder(int[] preOrder, int preOrderBegin, int preOrderEnd, int[] inOrder, int inOrderBegin, int inOrderEnd) {    if (preOrderBegin > preOrderEnd || inOrderBegin > inOrderEnd) {      return null;    }    int rootData = preOrder[preOrderBegin];//先序遍歷的第一個字符為當前序列根節點    Node head = new Node(rootData);    int divider = findIndexInArray(inOrder, rootData, inOrderBegin, inOrderEnd);//找打中序遍歷結果集中根節點的位置    int offSet = divider - inOrderBegin - 1;//計算左子樹共有幾個節點,節點數減一,為數組偏移量    Node left = buildTreePreOrderInOrder(preOrder, preOrderBegin + 1, preOrderBegin + 1 + offSet, inOrder, inOrderBegin,inOrderBegin + offSet);    Node right = buildTreePreOrderInOrder(preOrder, preOrderBegin + offSet + 2, preOrderEnd, inOrder, divider + 1, inOrderEnd);    head.left = left;    head.right = right;    return head;  }  /**   * 通過先序遍歷找到的rootData根節點,在中序遍歷結果中區分出:中左子樹和右子樹   * @param inOrder  中序遍歷的結果數組   * @param rootData  根節點位置   * @param begin  中序遍歷結果數組起始位置下標   * @param end  中序遍歷結果數組末尾位置下標   * @return return中序遍歷結果數組中根節點的位置   */  public int findIndexInArray(int[] inOrder, int rootData, int begin, int end) {    for (int i = begin; i <= end; i++) {      if (inOrder[i] == rootData)        return i;    }    return -1;  }  /**   * 二叉樹先序遍歷結果   * @param n   */  public void preOrder(Node n) {    if (n != null) {      System.out.print(n.val + ",");      preOrder(n.left);      preOrder(n.right);    }  }  /**   * 二叉樹中序遍歷結果   * @param n   */  public void inOrder(Node n) {    if (n != null) {      inOrder(n.left);      System.out.print(n.val + ",");      inOrder(n.right);    }  }  /**   * 還原后的二叉樹   * 二叉數層次遍歷   * 基本思想:   *   1.因為推導出來的二叉樹是保存在Node類對象的子對象里面的,(類似于c語言的結構體)如果通過遞歸實現層次遍歷的話,不容易實現   *   2.這里采用List隊列逐層保存Node對象節點的方式實現對二叉樹的層次遍歷輸出   *   3.如果父節點的位置為i,那么子節點的位置為,2i 和 2i+1;依據這個規律逐層遍歷,通過保存的父節點,找到子節點。并保存,不斷向下遍歷保存。   * @param tree   */  public void prototypeTree(Node tree){    //用list存儲層次遍歷的節點    if(tree !=null){      if(tree!=null)        nodeList.add(tree);      nodeList.add(tree.left);      nodeList.add(tree.right);      int count=3;      //從第三層開始      for(int i=3;count<treeNode;i++){        //第i層第一個子節點的父節點的位置下標        int index = (int) Math.pow(2, i-1-1)-1;        /**         * 二叉樹的每一層節點數遍歷         * 因為第i層的最大節點數為2的i-1次方個,         */        for(int j=1;j<=Math.pow(2, i-1);){          //計算有效的節點的個數,和遍歷序列的總數做比較,作為判斷循環結束的標志          if(nodeList.get(index).left!=null)            count++;          if(nodeList.get(index).right!=null)            count++;          nodeList.add(nodeList.get(index).left);          nodeList.add(nodeList.get(index).right);          index++;          if(count>=treeNode)//當所有有效節點都遍歷到了就結束遍歷            break;          j+=2;//每次存儲兩個子節點,所以每次加2        }      }      int flag=0,floor=1;      for(Node node:nodeList){        if(node!=null)          System.out.print(node.val+" ");        else          System.out.print("# ");//#號表示空節點        flag++;        /**         * 逐層遍歷輸出二叉樹         *          */        if(flag>=Math.pow(2, floor-1)){          flag=0;          floor++;          System.out.println();        }      }    }  }  /**   * 內部類   * 1.每個Node類對象為一個節點,   * 2.每個節點包含根節點,左子節點和右子節點   */  class Node {    Node left;    Node right;    int val;    public Node(int val) {      this.val = val;    }  }}

運行結果:

最后逐層輸出二叉樹的基本思想:

* 1.因為推導出來的二叉樹是保存在Node類對象的子對象里面的,(類似于c語言的結構體)如果通過遞歸實現層次遍歷的話,不容易實現

* 2.這里采用List隊列逐層保存Node對象節點的方式實現對二叉樹的層次遍歷輸出

* 3.如果父節點的位置為i,那么子節點的位置為,2i 和 2i+1;依據這個規律逐層遍歷,通過保存的父節點,找到子節點。并保存,不斷向下遍歷保存。

以上這篇通過先序遍歷和中序遍歷后的序列還原二叉樹(實現方法)就是小編分享給大家的全部內容了,希望能給大家一個參考,也希望大家多多支持武林網。

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表

圖片精選

亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
欧美精品电影在线| 亚洲精品动漫100p| 人人做人人澡人人爽欧美| 精品日韩视频在线观看| 日韩av中文字幕在线| 91手机视频在线观看| 2023亚洲男人天堂| 日韩高清不卡av| 久久精品国产精品亚洲| 欧美在线影院在线视频| 91高清视频在线免费观看| 欧美日韩国产一区二区| 中文字幕日韩电影| 亚洲国产精品99久久| 琪琪第一精品导航| 1769国产精品| 欧美成人精品h版在线观看| 萌白酱国产一区二区| 97久久精品视频| 亚洲精品成a人在线观看| 欧美人在线视频| 久久人91精品久久久久久不卡| 国产精品扒开腿做爽爽爽男男| 日韩精品中文字幕久久臀| 日韩一区av在线| 国产一区二区动漫| 亚洲精品在线看| 在线视频中文亚洲| 精品国内亚洲在观看18黄| 亚洲综合精品伊人久久| 亚洲精品永久免费精品| 欧美另类在线播放| 中文字幕日韩在线视频| 亚洲成人免费网站| 成人国产精品久久久久久亚洲| 亚洲深夜福利网站| 欧美一级黑人aaaaaaa做受| xxx一区二区| 黑人巨大精品欧美一区二区一视频| 97视频免费观看| 国产精品第一视频| 91高清视频在线免费观看| 欧美日韩免费观看中文| 久色乳综合思思在线视频| 日韩精品极品在线观看播放免费视频| 精品美女永久免费视频| 色与欲影视天天看综合网| 97国产精品久久| 26uuu亚洲国产精品| 国产91网红主播在线观看| 精品久久久久久久久国产字幕| 91国在线精品国内播放| 欧美黄色小视频| 美日韩丰满少妇在线观看| 国产视频久久网| 91香蕉国产在线观看| 精品久久久久久久久久| 中文字幕国产亚洲| 91精品国产电影| 日韩免费观看网站| 成人福利视频在线观看| 欧美亚洲成人免费| 成人激情在线播放| 91免费观看网站| 国产精品欧美风情| 日韩精品视频在线观看网址| 亚洲国产精品中文| 欧美激情亚洲一区| 亚洲成在人线av| 欧美日韩999| 亚洲精品午夜精品| 国产丝袜一区二区三区免费视频| 欧美日韩中文字幕在线视频| 日韩视频在线一区| 亚洲激情在线观看视频免费| 欧美另类第一页| 日韩一区二区三区在线播放| 国产97色在线|日韩| 精品国产一区久久久| 亚洲丁香久久久| 国产精品欧美一区二区三区奶水| 亚洲精品国产精品久久清纯直播| 久久中文字幕视频| 中文字幕免费精品一区高清| 欧美性猛交xxxx免费看久久久| 欧美激情在线有限公司| 久久久91精品国产一区不卡| 欧美又大粗又爽又黄大片视频| 亚洲天堂av在线播放| 91视频免费在线| 日韩免费观看网站| 亚洲精品一区二区网址| 一区二区三区精品99久久| 成人做爽爽免费视频| 亚洲人成在线一二| 欧美亚州一区二区三区| 欧美国产激情18| 日韩av免费网站| 欧美黑人巨大精品一区二区| 欧美成人免费网| 国产三级精品网站| 国产视频欧美视频| 亚洲欧美制服中文字幕| 中文字幕日韩免费视频| 日本成人黄色片| 欧美大胆在线视频| 日韩精品极品视频| 午夜免费久久久久| 久久免费国产视频| 国产精品久久久久久av| xxav国产精品美女主播| 国产精品色视频| 国产噜噜噜噜噜久久久久久久久| 97超碰蝌蚪网人人做人人爽| 亚洲一二三在线| 久久久精品中文字幕| 欧美人与性动交| 精品久久久久久久久久ntr影视| 精品国产美女在线| 亚洲精品有码在线| 欧美日韩国产一中文字不卡| 日韩在线视频一区| 亚洲人成网在线播放| 最近2019中文字幕在线高清| 精品精品国产国产自在线| 亚洲人成啪啪网站| 狠狠久久五月精品中文字幕| 亚洲一二在线观看| 久久精品在线播放| 中文欧美日本在线资源| 久久99久久99精品免观看粉嫩| 欧美成人国产va精品日本一级| 国内精品中文字幕| 亚洲高清一二三区| 久久夜色撩人精品| 久久大大胆人体| 精品亚洲一区二区| 久久在线免费观看视频| 91在线播放国产| 91青草视频久久| 日韩av免费在线观看| 精品日本高清在线播放| 美日韩精品免费观看视频| 欧美肥老太性生活视频| xvideos亚洲人网站| 亚洲一区二区三区视频播放| 亚洲综合日韩在线| 国内外成人免费激情在线视频| 51午夜精品视频| 亚洲精品欧美日韩专区| 欧美成人久久久| 在线性视频日韩欧美| 国产亚洲福利一区| 久久99视频免费| 亚洲色图第三页| 久久久久久久电影一区| 亚洲一区二区国产| www.日韩系列| 91超碰中文字幕久久精品| 色悠悠国产精品| 亚洲第一色在线| 亚洲成人网在线观看| 国产精品劲爆视频| 国产精品99久久久久久人|