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

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

数据结构与算法-二叉树(java描述)

發布時間:2025/3/20 编程问答 22 豆豆
生活随笔 收集整理的這篇文章主要介紹了 数据结构与算法-二叉树(java描述) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

一、概述

1.1、樹的概念
樹狀圖是一種數據結構,它是由n(n>=1)個有限節點組成一個具有層次關系的集合。把它叫做“樹”是因為它看起來像一棵倒掛的樹,也就是說它是根朝上,而葉朝下的。它具有以下的特點:
每個節點有零個或多個子節點;沒有父節點的節點稱為根節點;每一個非根節點有且只有一個父節點;除了根節點外,每個子節點可以分為多個不相交的子樹

1.2、樹的定義

樹(tree)是包含n(n>0)個結點的有窮集,其中:

(1)每個元素稱為結點(node);
(2)有一個特定的結點被稱為根結點或樹根(root)。
(3)除根結點之外的其余數據元素被分為m(m≥0)個互不相交的集合T1,T2,……Tm-1,其中每一個集合Ti(1<=i<=m)本身也是一棵樹,被稱作原樹的子樹(subtree)。
樹也可以這樣定義:樹是由根結點和若干顆子樹構成的。樹是由一個集合以及在該集合上定義的一種關系構成的。集合中的元素稱為樹的結點,所定義的關系稱為父子關系。父子關系在樹的結點之間建立了一個層次結構。在這種層次結構中有一個結點具有特殊的地位,這個結點稱為該樹的根結點,或稱為樹根。
我們可以形式地給出樹的遞歸定義如下:
單個結點是一棵樹,樹根就是該結點本身。
設T1,T2,…,Tk是樹,它們的根結點分別為n1,n2,…,nk。用一個新結點n作為n1,n2,…,nk的父親,則得到一棵新樹,結點n就是新樹的根。我們稱n1,n2,…,nk為一組兄弟結點,它們都是結點n的子結點。我們還稱T1,T2,…,Tk為結點n的子樹。
空集合也是樹,稱為空樹。空樹中沒有結點。

二、二叉樹

2.1、概述

在計算機科學中,二叉樹是每個節點最多有兩個子樹的樹結構。通常子樹被稱作“左子樹”(left subtree)和“右子樹”(right subtree)。二叉樹常被用于實現二叉查找樹和二叉堆。
二叉樹的每個結點至多只有二棵子樹(不存在度大于2的結點),二叉樹的子樹有左右之分,次序不能顛倒。二叉樹的第i層至多有2{i-1}個結點;深度為k的二叉樹至多有2k-1個結點;對任何一棵二叉樹T,如果其終端結點數為n_0,度為2的結點數為n_2,則n_0=n_2+1。
一棵深度為k,且有2^k-1個節點稱之為滿二叉樹;深度為k,有n個節點的二叉樹,當且僅當其每一個節點都與深度為k的滿二叉樹中,序號為1至n的節點對應時,稱之為完全二叉樹。

2.2、二叉樹實現
看到上面的概念之后,下面將進行二叉樹數據結構的實現

2.2.1、二叉樹抽象類

BinaryTreeADT.java:

package sihai;import java.util.Iterator;/*** BinaryTreeADT是二叉樹的抽象接口**/ public interface BinaryTreeADT<T> {/** *返回根節點元素**/public T getRootElement();/** * 判斷二叉樹是否為空*/public boolean isEmpty();/** * 返回二叉樹中元素的數量*/public int size();/** * 判斷二叉樹中是否存在特定的目標元素*/public boolean contains(T targetElement);/** * 查找目標元素** @param targetElement 在二叉樹中查找的元素*/public T find(T targetElement);/** * */public String toString();/** * 返回這顆樹的迭代器*/public Iterator<T> iterator();/** * 中序遍歷*/public Iterator<T> iteratorInOrder();/** * 前序遍歷 */public Iterator<T> iteratorPreOrder();/** * 后序遍歷*/public Iterator<T> iteratorPostOrder();/** * 層次遍歷 */public Iterator<T> iteratorLevelOrder(); }

2.2.2、二叉樹的節點類

package sihai;/*** 二叉樹節點類,包括左節點和右節點,本身節點元素* */ public class BinaryTreeNode<T> {protected T element;protected BinaryTreeNode<T> left, right;/*** 創建一個特定值得節點** @param obj 新的節點的元素*/public BinaryTreeNode(T obj) {element = obj;left = null;right = null;}/*** 創建一個特定值得節點** @param obj 新的節點的元素* @param left 節點的左子樹* @param right 節點的右子樹*/public BinaryTreeNode(T obj, LinkedBinaryTree<T> left, LinkedBinaryTree<T> right) {element = obj;if (left == null)this.left = null;elsethis.left = left.getRootNode();if (right == null)this.right = null;elsethis.right = right.getRootNode();}/*** 節點總數**/public int numChildren() {int children = 0;if (left != null)children = 1 + left.numChildren();if (right != null)children = children + 1 + right.numChildren();return children;}/*** 返回節點元素**/public T getElement() {return element;}/***返回節點的右節點*/public BinaryTreeNode<T> getRight() {return right;}/*** 設置節點的右節點*/public void setRight(BinaryTreeNode<T> node) {right = node;}/***返回節點的左節點*/public BinaryTreeNode<T> getLeft() {return left;}/*** 設置節點的左節點*/public void setLeft(BinaryTreeNode<T> node) {left = node;} }

通過上面的二叉樹的抽象類和節點類,大概的二叉樹的數據結構已經出來了,下面我們再討論二叉樹的另外一種實現,看看如何用鏈表來實現二叉樹。

三、用鏈表實現二叉樹

鏈表二叉樹實現了BinaryTreeADT接口的LinkedBinaryTree類,需要跟蹤位于樹的根節點,一節樹的元素數目。

package sihai;import java.util.*; import jsjf.exceptions.*;/*** 鏈表二叉樹實現二叉樹接口*/ public class LinkedBinaryTree<T> implements BinaryTreeADT<T>, Iterable<T> {protected BinaryTreeNode<T> root; //二叉樹根節點protected int modCount;/*** 創建空的鏈接二叉樹*/public LinkedBinaryTree() {root = null;}/*** 創建一個帶有特定元素的節點作為二叉樹的根** @param 根節點的元素*/public LinkedBinaryTree(T element) {root = new BinaryTreeNode<T>(element);}/*** 創建一個帶有特定元素的節點作為二叉樹的根,并且設置其左子樹和右子樹** @param 根元素* @param 樹的左子樹* @param 樹的右子樹*/public LinkedBinaryTree(T element, LinkedBinaryTree<T> left, LinkedBinaryTree<T> right) {root = new BinaryTreeNode<T>(element);root.setLeft(left.root);root.setRight(right.root);}/*** 返回根節元素*/public T getRootElement() throws EmptyCollectionException{// TODO}/***返回根節點*/protected BinaryTreeNode<T> getRootNode() throws EmptyCollectionException{//TODO}/*** 返回樹的根節點的左子樹**/public LinkedBinaryTree<T> getLeft(){//TODO}/*** 返回樹的根節點的右子樹**/public LinkedBinaryTree<T> getRight(){//TODO}/*** 判斷二叉樹是否為空**/public boolean isEmpty() {return (root == null);}/*** 返回樹的大小**/public int size() {// TODO}/*** 返回樹的高度**/public int getHeight(){//TODO}/*** 返回特定節點的樹的高度**/private int height(BinaryTreeNode<T> node) {//TODO}/*** 判斷樹是否包含目標元素*/public boolean contains(T targetElement) {// TODO}/*** 根據目標元素查找節點*/public T find(T targetElement) throws ElementNotFoundException{BinaryTreeNode<T> current = findNode(targetElement, root);if (current == null)throw new ElementNotFoundException("LinkedBinaryTree");return (current.getElement());}/***根據特定的元素查找目標節點*/private BinaryTreeNode<T> findNode(T targetElement, BinaryTreeNode<T> next){if (next == null)return null;if (next.getElement().equals(targetElement))return next;BinaryTreeNode<T> temp = findNode(targetElement, next.getLeft());if (temp == null)temp = findNode(targetElement, next.getRight());return temp;}public String toString() {// TODO}/*** 返回中序遍歷迭代器**/public Iterator<T> iterator(){return iteratorInOrder();}public Iterator<T> iteratorInOrder(){ArrayUnorderedList<T> tempList = new ArrayUnorderedList<T>();inOrder(root, tempList);return new TreeIterator(tempList.iterator());}/*** 中序遍歷*/protected void inOrder(BinaryTreeNode<T> node, ArrayUnorderedList<T> tempList) {if (node != null){inOrder(node.getLeft(), tempList);tempList.addToRear(node.getElement());inOrder(node.getRight(), tempList);}}/*** 前序遍歷*/public Iterator<T> iteratorPreOrder() {//TODO}/*** 前序遍歷*/protected void preOrder(BinaryTreeNode<T> node, ArrayUnorderedList<T> tempList) {// TODO}/*** 后序遍歷*/public Iterator<T> iteratorPostOrder() {// TODO}/*** 后序遍歷*/protected void postOrder(BinaryTreeNode<T> node, ArrayUnorderedList<T> tempList) {// TODO}/*** 層次遍歷*/public Iterator<T> iteratorLevelOrder() {ArrayUnorderedList<BinaryTreeNode<T>> nodes = new ArrayUnorderedList<BinaryTreeNode<T>>();ArrayUnorderedList<T> tempList = new ArrayUnorderedList<T>();BinaryTreeNode<T> current;nodes.addToRear(root);while (!nodes.isEmpty()) {current = nodes.removeFirst();if (current != null){tempList.addToRear(current.getElement());if (current.getLeft() != null)nodes.addToRear(current.getLeft());if (current.getRight() != null)nodes.addToRear(current.getRight());}elsetempList.addToRear(null);}return new TreeIterator(tempList.iterator());}/*** 表示樹的元素的迭代器的內部類*/private class TreeIterator implements Iterator<T>{private int expectedModCount;private Iterator<T> iter;public TreeIterator(Iterator<T> iter){this.iter = iter;expectedModCount = modCount;}public boolean hasNext() throws ConcurrentModificationException{if (!(modCount == expectedModCount))throw new ConcurrentModificationException();return (iter.hasNext());}public T next() throws NoSuchElementException{if (hasNext())return (iter.next());else throw new NoSuchElementException();}public void remove(){throw new UnsupportedOperationException();}} }

四、二叉樹的應用

我們都知道用棧算法可以實現后綴表達式的計算,但是,其實用二叉樹也是可以同樣實現的,下面就創建一個ExpressionTree類來對這一算法進行實現。
在這之前,我們需要一個ExpressionTreeOp的操作輔助類,這個類可以跟蹤記錄該元素是一個數字還是一個操作符,以及該處存儲的是哪個操作符或是什么值。

ExpressionTreeOp.java:

package sihai;/*** 表達式樹的操作類*/ public class ExpressionTreeOp {private int termType;private char operator;private int value;/*** 創建一個新的操作表達式樹** @param type 元素類型* @param op 操作符* @param val 操作值*/public ExpressionTreeOp(int type, char op, int val) {termType = type;operator = op;value = val;}/*** 判斷是否是運算符*/public boolean isOperator() {return (termType == 1);}/***返回運算符*/public char getOperator() {return operator;}/***返回值*/public int getValue() {return value;}public String toString(){if (termType == 1) return operator + "";elsereturn value + "";} }

下面就是表達式樹的類

ExpressinTree.java:

package sihai;/*** 表示一個表達式樹的操作數的操作值得*/ public class ExpressionTree extends LinkedBinaryTree<ExpressionTreeOp> {public ExpressionTree() {super();}/*** 創建一個有左子樹和右子樹的表達式樹*/public ExpressionTree(ExpressionTreeOp element,ExpressionTree leftSubtree, ExpressionTree rightSubtree) {root = new BinaryTreeNode<ExpressionTreeOp>(element, leftSubtree, rightSubtree);}/*** 評測表達式樹*/public int evaluateTree() {return evaluateNode(root);}/*** 評測節點*/public int evaluateNode(BinaryTreeNode root) {int result, operand1, operand2;ExpressionTreeOp temp;if (root==null)result = 0;else{temp = (ExpressionTreeOp)root.getElement();if (temp.isOperator()){operand1 = evaluateNode(root.getLeft());operand2 = evaluateNode(root.getRight());result = computeTerm(temp.getOperator(), operand1, operand2);}elseresult = temp.getValue();}return result;}/*** 計算表達式的值*/private static int computeTerm(char operator, int operand1, int operand2){int result=0;if (operator == '+')result = operand1 + operand2;else if (operator == '-')result = operand1 - operand2;else if (operator == '*')result = operand1 * operand2;else result = operand1 / operand2;return result;}/*** 打印樹*/public String printTree() {UnorderedListADT<BinaryTreeNode<ExpressionTreeOp>> nodes = new ArrayUnorderedList<BinaryTreeNode<ExpressionTreeOp>>();UnorderedListADT<Integer> levelList = new ArrayUnorderedList<Integer>();BinaryTreeNode<ExpressionTreeOp> current;String result = "";int printDepth = this.getHeight();int possibleNodes = (int)Math.pow(2, printDepth + 1);int countNodes = 0;nodes.addToRear(root);Integer currentLevel = 0;Integer previousLevel = -1;levelList.addToRear(currentLevel);while (countNodes < possibleNodes) {countNodes = countNodes + 1;current = nodes.removeFirst();currentLevel = levelList.removeFirst();if (currentLevel > previousLevel){result = result + "\n\n";previousLevel = currentLevel;for (int j = 0; j < ((Math.pow(2, (printDepth - currentLevel))) - 1); j++)result = result + " ";}else{for (int i = 0; i < ((Math.pow(2, (printDepth - currentLevel + 1)) - 1)) ; i++) {result = result + " ";}}if (current != null){result = result + (current.getElement()).toString();nodes.addToRear(current.getLeft());levelList.addToRear(currentLevel + 1);nodes.addToRear(current.getRight());levelList.addToRear(currentLevel + 1);}else {nodes.addToRear(null);levelList.addToRear(currentLevel + 1);nodes.addToRear(null);levelList.addToRear(currentLevel + 1);result = result + " ";}}return result;} }

總結

以上是生活随笔為你收集整理的数据结构与算法-二叉树(java描述)的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。