1. 程式人生 > >資料結構--樹(Java版)

資料結構--樹(Java版)

一、樹節點的表示

/**
 * 樹的節點
 * @author hoaven
 *
 */
public class TreeNode<T> {
    T data;
    TreeNode<T> left;
    TreeNode<T> right;

    public TreeNode(T data){
        this.data = data;
    }

}

二、樹的前中後序遍歷

1、實現

/**
 * 實現樹的前序,中序,後續遍歷搜尋
 *
 * @author hoaven
 * @see TreeNode
 */
public class TreeSearch<T> { StringBuffer searchPath = new StringBuffer(); private boolean isSearched = false; /** * 前序遍歷root查詢item * * @return */ public void preorderTraversal(TreeNode<T> root, T data) { if (root == null) { return; } if
(!isSearched) { //記錄遍歷路徑 if (!searchPath.toString().equals("")) { searchPath.append("->"); } searchPath.append(root.data); //先判斷根 if (root.data.equals(data)) isSearched = true; } if
(!isSearched) preorderTraversal(root.left, data); if (!isSearched) preorderTraversal(root.right, data); } /** * 中序遍歷root查詢item * * @param root * @return */ public void inorderTraversal(TreeNode<T> root, T data) { if (root == null) { return; } if (!isSearched) inorderTraversal(root.left, data); if (!isSearched) { if (!searchPath.toString().equals("")) { searchPath.append("->"); } searchPath.append(root.data); if (root.data.equals(data)) isSearched = true; } if (!isSearched) inorderTraversal(root.right, data); } /** * 後續遍歷root查詢item * * @return */ public void postorderTraversal(TreeNode<T> root, T data) { if (root == null) { return; } if (!isSearched) postorderTraversal(root.left, data); if (!isSearched) postorderTraversal(root.right, data); if (!isSearched) { if (!searchPath.toString().equals("")) { searchPath.append("->"); } searchPath.append(root.data); if (root.data.equals(data)) isSearched = true; } } }

2、測試

/**
 * TreeSearch測試類
 * @author hoaven
 * @see TreeSearch
 * @see TreeNode
 */
public class TreeSearchTest {

    private static TreeNode<Integer> root;

    @BeforeClass
    public static void beforeClass(){
        TreeNode<Integer> node1 = new TreeNode<Integer>(1);
        TreeNode<Integer> node2 = new TreeNode<Integer>(2);
        TreeNode<Integer> node3 = new TreeNode<Integer>(3);
        TreeNode<Integer> node4 = new TreeNode<Integer>(4);
        TreeNode<Integer> node5 = new TreeNode<Integer>(5);
        TreeNode<Integer> node6 = new TreeNode<Integer>(6);
        TreeNode<Integer> node7 = new TreeNode<Integer>(7);
        TreeNode<Integer> node8 = new TreeNode<Integer>(8);
        TreeNode<Integer> node9 = new TreeNode<Integer>(9);
        TreeNode<Integer> node10 = new TreeNode<Integer>(10);

        node1.left = node2;
        node1.right = node3;

        node2.left = node4;
        node2.right = node5;

        node3.left = node6;
        node3.right = node7;

        node4.left = node8;

        node7.right = node9;

        node9.left = node10;

        root = node1;
    }

    /**
     * 前序遍歷測試
     */
    @Test
    public void preorderTraversalTest(){
        TreeSearch<Integer> treeSearch = new TreeSearch<Integer>();

        Integer value = 5;
        String expectedSearchPath = "1->2->4->8->5";
        treeSearch.preorderTraversal(root, value);
        Assert.assertTrue(expectedSearchPath.equals(treeSearch.searchPath.toString()));

        treeSearch = new TreeSearch<Integer>();

        value = 6;
        expectedSearchPath = "1->2->4->8->5->3->6";
        treeSearch.preorderTraversal(root, value);
        Assert.assertTrue(expectedSearchPath.equals(treeSearch.searchPath.toString()));
    }

    /**
     * 中序遍歷測試
     */
    @Test
    public void inorderTraversalTest(){
        TreeSearch<Integer> treeSearch = new TreeSearch<Integer>();

        Integer value = 5;
        String expectedSearchPath = "8->4->2->5";
        treeSearch.inorderTraversal(root, value);
        Assert.assertTrue(expectedSearchPath.equals(treeSearch.searchPath.toString()));

        treeSearch = new TreeSearch<Integer>();

        value = 6;
        expectedSearchPath = "8->4->2->5->1->6";
        treeSearch.inorderTraversal(root, value);
        Assert.assertTrue(expectedSearchPath.equals(treeSearch.searchPath.toString()));
    }

    /**
     * 後序遍歷測試
     */
    @Test
    public void postorderTraversalTest(){
        TreeSearch<Integer> treeSearch = new TreeSearch<Integer>();

        Integer value = 5;
        String expectedSearchPath = "8->4->5";
        treeSearch.postorderTraversal(root, value);
        Assert.assertTrue(expectedSearchPath.equals(treeSearch.searchPath.toString()));

        treeSearch = new TreeSearch<Integer>();

        value = 6;
        expectedSearchPath = "8->4->5->2->6";
        treeSearch.postorderTraversal(root, value);
        Assert.assertTrue(expectedSearchPath.equals(treeSearch.searchPath.toString()));
    }
}

2、二叉查詢樹判斷

  • 二叉樹:每個節點最多有兩個子樹的樹結構。通常子樹被稱作“左子樹”和“右子樹”。
  • 二叉查詢樹:對所有節點來說,所有左子樹節點都小於等於其根節點;所有右子樹節點都大於其根節點。
/**
 * 二叉查詢樹的判斷<br>
 * @author hoaven
 * @see TreeNode
 */
public class BinarySearchTree {

    /**
     * Check root左子樹所有節點小於等於max,root右子樹所有節點大於min
     * 
     * @param root
     * @param min
     * @param max
     * @return
     */
    private static boolean checkBSTMinMax(TreeNode<Integer> root, Integer min, Integer max){
        if(root  == null){
            return true;
        }

        if(root.data > max || root.data <= min){
            return false;
        }

        if(!checkBSTMinMax(root.left, min, root.data) || !checkBSTMinMax(root.right, root.data, max)){
            return false;
        }

        return true;
    }

    /**
     * Check root是否二叉查詢樹
     * @param root
     * @return
     */
    public static boolean checkBST(TreeNode<Integer> root){
        return checkBSTMinMax(root, Integer.MIN_VALUE, Integer.MAX_VALUE);
    }
}