1. 程式人生 > >用Java實現一個二叉樹

用Java實現一個二叉樹

子節點 -o 分享 roo 添加 return 葉子節點 ont java實現

介紹

使用Java實現一個int值類型的排序二叉樹

二叉樹

二叉樹是一個遞歸的數據結構,每個節點最多有兩個子節點。
通常二叉樹是二分查找樹,每個節點它的值大於或者等於在它左子樹節點上的值,小於或者等於在它右子樹節點上的值,如下圖
技術分享圖片

為了實現二叉樹,我們使用一個Node類來表示節點,節點存儲int類型的值,還有對子節點的引用。

package com.java.node.BinaryTree;
public class Node {
    int data;
    Node left;
    Node right;
    public Node(int data) {
        this.data = data;
        this.left = null;
        this.right = null;
    }
}

然後添加樹的root節點

package com.java.node.BinaryTree;
public class BinaryTree {
    Node root;
}

通常的操作

添加節點

首先我們必須找到新節點的位置,是為了保持樹排序。我們必須從root節點開始,必須遵循下面的規則:

  • 如果新節點小於當前的值,我們將會進入左子樹
  • 如果新節點大於當前的節點。我們將會進入右子樹
  • 當當前的節點是null時,我們已經到達葉子節點,我們可以添加新節點到這個位置。
    我們將會創建遞歸方法做添加節點操作
    private Node addNode(Node current, int value) {
        if (current == null) {
            return new Node(value);
        }
        if (value < current.data) {
            current.left = addNode(current.left, value);
        } else if (value > current.data) {
            current.right = addNode(current.right, value);
        } else {
            return current;
        }
        return current;
    }
    public void addNode(int value) {
        root = addNode(root, value);
    }

可以使用方法創建一個二叉樹了

public BinaryTree createBinaryTree() {
        BinaryTree bt = new BinaryTree();
        bt.addNode(6);
        bt.addNode(4);
        bt.addNode(8);
        bt.addNode(10);
        return bt;
    }

查找一個節點

    private boolean containNode(Node current, int value) {
        if (current == null) {
            return false;
        }
        if (value == current.data) {
            return true;
        }
        return value < current.data ? containNode(current.left, value) : containNode(current.right, value);
    }
    public boolean containNode(int value) {
        return containNode(root, value);
    }

刪除一個節點

private Node deleteNode(Node current, int value) {
        if (current == null) {
            return null;
        }
        if (value == current.data) {
            if (current.left == null && current.right == null) {
                return null;
            }
            if (current.left == null) {
                return current.right;
            }
            if (current.right == null) {
                return current.left;
            }
            int smallestValue = findSmallestValue(current.right);
            current.data = smallestValue;
            current.right = deleteNode(current.right, smallestValue);
            return current;
        }
        if (value < current.data) {
            current.left = deleteNode(current.left, value);
            return current;
        }
        current.right = deleteNode(current.right, value);
        return current;
    }
    private int findSmallestValue(Node root) {
        return root.left == null ? root.data : findSmallestValue(root.right);
    }

遍歷樹

我們將以不同的方式遍歷樹,以depth-first,breadth-first方式遍歷樹。
以Depth-First遍歷樹
Depth-first查詢是一種在查詢兄弟節點之前,盡可能的查詢每個子節點。
in-order,pre-order,post-order方式都是以depth-first方式遍歷樹的。

in-order遍歷是首先遍歷左子樹,然後root節點,最後是右子樹。

    public void traverseInOrder(Node root) {
        if (root != null) {
            traverseInOrder(root.left);
            System.out.println(root.data);
            traverseInOrder(root.right);
        }
    }

pre-order遍歷首先是root節點,然後是左子樹,最後是右子樹。

public void traversePreOrder(Node root) {
        if (root != null) {
            System.out.println(root.data);
            traversePreOrder(root.left);
            traversePreOrder(root.right);
        }
    }

post-order遍歷首先是遍歷左子樹,然後是右子樹,最後是root節點。

public void traversePostOrder(Node root) {
        if (root != null) {
            traversePostOrder(root.left);
            traversePostOrder(root.right);
            System.out.println(root.data);
        }
    }

以Breadth-First遍歷
它在遍歷下一級的節點之前,會遍歷當前級的所有節點。
這種類型的遍歷也叫做level-order,遍歷樹從root節點開始,從左到右。
為了實現,使用隊列來存儲每個級別的節點。我們將會從列表中獲取每個節點。然後添加他的子節點到隊列中。

public void traverseLevelOrder(Node root) {
        if (root == null) {
            return;
        }
        Queue<Node> nodes = new LinkedList<Node>();
        nodes.add(root);
        while(!nodes.isEmpty()) {
            Node node = nodes.remove();
            System.out.println(node.data);
            if (node.left != null) {
                nodes.add(node.left);
            }
                        
            if (node.right != null) {
                nodes.add(node.right);
            }
        }
    }

用Java實現一個二叉樹