演算法與資料結構面試題(18)-二叉樹鏡像__JAVA

來源:互聯網
上載者:User
題目


輸入一顆二元尋找樹,將該樹轉換為它的鏡像,即在轉換後的二元尋找樹中,左子樹的結點都大於右子樹的結點。用遞迴和迴圈兩種方法完成樹的鏡像轉換。




解題思路


遞迴遍曆每個結點,然後轉換左右結點。


代碼


前人寫的二叉樹java類,直接拿過來用。但是它的中序和後續的遍曆代碼調用了前序的代碼,需要修改下。


/** * 二叉樹的二叉鏈表表示 */public class BinaryTree<T> {private TreeNode root; // 根節點public BinaryTree() {}public BinaryTree(TreeNode root) {this.root = root;}/** * 定義節點 內部類 */private static class TreeNode<T> {private T data = null; // 資料部分private TreeNode lchild; // 左節點的引用private TreeNode rchild; // 右節點的引用protected TreeNode() {}protected TreeNode(T data, TreeNode lchild, TreeNode rchild) {this.data = data;this.lchild = lchild;this.rchild = rchild;}private T getData() {return data;}private void setData(T data) {this.data = data;}private TreeNode getLchild() {return lchild;}private void setLchild(TreeNode lchild) {this.lchild = lchild;}private TreeNode getRchild() {return rchild;}private void setRchild(TreeNode rchild) {this.rchild = rchild;}}/** * 返回父結點 * * @param element * @return */public TreeNode getParent(TreeNode element) {// 如果傳入參數為根節點或根節點為空白,返回nullreturn (root == null || root == element) ? null : parent(root, element);}/** * @param subTree * @param element * @return */public TreeNode parent(TreeNode subTree, TreeNode element) {if (subTree == null) {return null;}// 如果subTree的左孩子節點或右孩子節點等於element,則返回subTreeif (subTree.getLchild() == element || subTree.getRchild() == element) {// 返回父結點地址return subTree;}TreeNode p;// 現在左子樹中找,如果左子樹中沒有找到,才到右子樹去找if ((p = parent(subTree.getLchild(), element)) != null) {// 遞迴在左子樹中搜尋return p;} else {// 遞迴在右子樹中搜尋return parent(subTree.getRchild(), element);}}/** * 節點個數 * * @return */public int getSize() {return getNum(root);}private int getNum(TreeNode node) {if (node == null) {return 0;} else {int i = getNum(node.getLchild());int j = getNum(node.getRchild());return j + i + 1;}}/** * 樹高度 * * @return */public int getHeight() {return getHeight(root);}private int getHeight(TreeNode tree) {if (tree == null)return 0;// 遞迴結束:空樹高度為0else {int i = getHeight(tree.getLchild());int j = getHeight(tree.getRchild());return (i < j) ? (j + 1) : (i + 1);}}/** * 前序走訪 先訪問根結點,然後遍曆左子樹,最後遍曆右子樹 * * @param node */public void preOrder(TreeNode node) {if (node != null) {System.out.println(node.getData());preOrder(node.getLchild());preOrder(node.getRchild());}}/** * 中序遍曆 首先遍曆左子樹,然後訪問根結點,最後遍曆右子樹 * * @param node */public void inOrder(TreeNode node) {if (node != null) {inOrder(node.getLchild());System.out.println(node.getData());inOrder(node.getRchild());}}/** * 後序遍曆 首先遍曆左子樹,然後遍曆右子樹,最後遍曆訪問根結點 * * @param node */public void postOrder(TreeNode node) {if (node != null) {postOrder(node.getLchild());postOrder(node.getRchild());System.out.println(node.getData());}}public static void main(String[] args) {TreeNode leaf1 = new TreeNode("5", null, null); // 沒有左右孩子節點TreeNode leaf2 = new TreeNode("7", null, null); // 沒有左右孩子節點TreeNode leaf3 = new TreeNode("9", null, null); // 沒有左右孩子節點TreeNode leaf4 = new TreeNode("11", null, null); // 沒有左右孩子節點TreeNode n3 = new TreeNode("6", leaf1, leaf2); // 根節點左子樹TreeNode n4 = new TreeNode("10", leaf3, leaf4); // 根節點右子樹TreeNode root = new TreeNode("8", n3, n4); // 建立根節點BinaryTree bt = new BinaryTree(root);System.out.println("=======先序遍曆======");bt.preOrder(bt.root);System.out.println("=======中序遍曆======");bt.inOrder(bt.root);System.out.println("========後續遍曆=======");bt.postOrder(bt.root);System.out.println("===========");//System.out.println(bt.getHeight());//System.out.println(bt.getSize());////System.out.println(bt.getParent(leaf1).getData());}}


現在我們來前序走訪二叉樹的同事,再顛倒左右孩子。在前序走訪的方法裡做一些修改。


//前序走訪並顛倒左右子樹public void preOrderAndTransform(TreeNode node) {if (node != null) {// System.out.println(node.getData());// 先儲存左孩子結點TreeNode lNode = node.getLchild();node.setLchild(node.getRchild());node.setRchild(lNode);preOrderAndTransform(node.getLchild());preOrderAndTransform(node.getRchild());}}

測試程式:


public static void main(String[] args) {TreeNode leaf1 = new TreeNode("5", null, null); // 沒有左右孩子節點TreeNode leaf2 = new TreeNode("7", null, null); // 沒有左右孩子節點TreeNode leaf3 = new TreeNode("9", null, null); // 沒有左右孩子節點TreeNode leaf4 = new TreeNode("11", null, null); // 沒有左右孩子節點TreeNode n3 = new TreeNode("6", leaf1, leaf2); // 根節點左子樹TreeNode n4 = new TreeNode("10", leaf3, leaf4); // 根節點右子樹TreeNode root = new TreeNode("8", n3, n4); // 建立根節點BinaryTree bt = new BinaryTree(root);System.out.println("=======先序遍曆======");bt.preOrder(bt.root);System.out.println("=======中序遍曆======");bt.inOrder(bt.root);System.out.println("========後續遍曆=======");bt.postOrder(bt.root);System.out.println("======鏡像=====");// 鏡像顛倒bt.preOrderAndTransform(bt.root);System.out.println("=======先序遍曆======");bt.preOrder(bt.root);System.out.println("=======中序遍曆======");bt.inOrder(bt.root);System.out.println("========後續遍曆=======");bt.postOrder(bt.root);// System.out.println(bt.getHeight());// System.out.println(bt.getSize());//// System.out.println(bt.getParent(leaf1).getData());}

輸出


=======先序遍曆======865710911=======中序遍曆======567891011========後續遍曆=======576911108顛倒後 : =======先序遍曆======810119675=======中序遍曆======111098765========後續遍曆=======119107568


迴圈的話使用while。用遊標指向下一個待轉換的結點,直到結點的左右孩子都為空白。否則顛倒2個字結點。



聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.