1. 程式人生 > >二叉樹的建樹、遍歷(先序、中序、後序、層次)(遞迴和非遞迴)--Java實現

二叉樹的建樹、遍歷(先序、中序、後序、層次)(遞迴和非遞迴)--Java實現

什麼是樹?什麼是二叉樹?
樹:除了根節點之外的所有節點都有且只有一個父節點,根節點沒有父節點;除了葉結點以外的所有節點,都有一個或多個子節點,葉結點沒有子節點。
二叉樹:是樹的一種特殊結構,在二叉樹中,每個節點最多隻能有兩個子節點。
二叉樹的遍歷方式:
1、先序遍歷(遞迴、非遞迴);
2、中序遍歷(遞迴、非遞迴);
3、後序遍歷(遞迴、非遞迴);
4、層次遍歷。

建樹、遍歷程式碼:

public class BinaryTree<E> {

    private static class Node<E>{
        public
E value; //節點值 public Node<E> left; //左節點 public Node<E> right;//右節點 public Node(E value) { this.value = value; this.left = null; this.right = null; } } public static List<Node<Integer>> nodeList = null;//用於儲存二叉樹的節點
/** * 建立陣列 * @param length * @return */ public int[] createArray(int length){ int[] array = new int[length]; for (int i = 0; i < array.length; i++) { array[i] = (int)(Math.random() * 100); } return array; } /** * 建立二叉樹 */
public void createBinaryTree(int nodeNum){ nodeList = new ArrayList<Node<Integer>>(); int[] array = createArray(nodeNum); for(int i : array){ System.out.print(i + " "); } System.out.println(); for (int i = 0; i < array.length; i++) { Node<Integer> temp = new Node<Integer>(array[i]); nodeList.add(temp); } for (int parentIndex = 0; parentIndex < array.length/2 - 1; parentIndex++) { //父節點 Node<Integer> parentNode = nodeList.get(parentIndex); //左節點 parentNode.left = nodeList.get(parentIndex * 2 + 1); //右節點 parentNode.right = nodeList.get(parentIndex * 2 + 2); int lastParentIndex = array.length/2 - 1; Node<Integer> lastParentNode = nodeList.get(lastParentIndex); lastParentNode.left = nodeList.get(lastParentIndex * 2 + 1); //總節點數為基數,最後一個父節點才有右孩子 if (array.length % 2 == 1) { lastParentNode.right = nodeList.get(lastParentIndex * 2 + 2); } } } /** * 二叉樹先序遍歷(遞迴) * @param parentNode */ public void BinaryTreePreOrder(Node<E> parentNode){ if (parentNode == null) { return; } System.out.print(parentNode.value + " "); BinaryTreePreOrder(parentNode.left); BinaryTreePreOrder(parentNode.right); } /** * 二叉樹先序遍歷(迴圈) * @param rootNode */ public void BinaryTreePreOrder_loop(Node<E> rootNode){ Stack<Node<E>> stack = new Stack<Node<E>>(); Node<E> cur = rootNode; while(cur != null || !stack.isEmpty()){ while(cur != null){ System.out.print(cur.value + " "); stack.push(cur); cur = cur.left; } cur = stack.pop(); cur = cur.right; } } /** * 二叉樹中序遍歷(遞迴) * @param parentNode */ public void BinaryTreeMidOrder(Node<E> parentNode){ if (parentNode == null) { return; } BinaryTreeMidOrder(parentNode.left); System.out.print(parentNode.value + " "); BinaryTreeMidOrder(parentNode.right); } /** * 二叉樹中序遍歷(迴圈) * @param rootNode */ public void BinaryTreeMidOrder_loop(Node<E> rootNode){ Stack<Node<E>> stack = new Stack<Node<E>>(); Node<E> cur = rootNode; while(cur != null || !stack.isEmpty()){ while(cur != null){ stack.push(cur); cur = cur.left; } cur = stack.pop(); System.out.print(cur.value + " "); cur = cur.right; } } /** * 二叉樹後序遍歷(遞迴) * @param parentNode */ public void BinaryTreePostOrder(Node<E> parentNode){ if (parentNode == null) { return; } BinaryTreePostOrder(parentNode.left); BinaryTreePostOrder(parentNode.right); System.out.print(parentNode.value + " "); } /** * 二叉樹後序遍歷(非遞迴) * 先處理左右子樹,再處理根 * @param rootNode */ public void BinaryTreePostOrder_loop(Node<E> rootNode){ Stack<Node<E>> stack = new Stack<Node<E>>(); //使用map來標記已經訪問過的節點 Map<Node<E>, Boolean> nodeMap = new HashMap<Node<E>, Boolean>(); stack.push(rootNode); while(!stack.isEmpty()){ Node<E> temp = stack.peek(); //獲取左子樹的左節點 if (temp.left != null && !nodeMap.containsKey(temp.left)) { temp = temp.left; while(temp != null){ stack.push(temp); temp = temp.left; } continue; } //獲取右節點 if (temp.right != null && !nodeMap.containsKey(temp.right)) { stack.push(temp.right); continue; } Node<E> cur = stack.pop(); System.out.print(cur.value + " "); nodeMap.put(cur, true); } } /** * 二叉樹層次遍歷 * @param rootNode */ public void BinaryTreeLevelOrder(Node<E> rootNode){ //使用佇列來實現遍歷 Queue<Node<E>> queue = new LinkedList<Node<E>>(); queue.add(rootNode); while(!queue.isEmpty()){ Node<E> parentNode = queue.poll(); System.out.print(parentNode.value + " "); if (parentNode.left != null) { queue.add(parentNode.left); } if (parentNode.right != null) { queue.add(parentNode.right); } } } public static void main(String[] args) { BinaryTree<Integer> tree = new BinaryTree<Integer>(); System.out.println("遍歷前陣列:"); tree.createBinaryTree(11); Node<Integer> rootNode = nodeList.get(0); System.out.println("先序遍歷(遞迴):"); tree.BinaryTreePreOrder(rootNode); System.out.println(); System.out.println("先序遍歷(非遞迴):"); tree.BinaryTreePreOrder_loop(rootNode); System.out.println(); System.out.println("中序遍歷(遞迴):"); tree.BinaryTreeMidOrder(rootNode); System.out.println(); System.out.println("中序遍歷(非遞迴):"); tree.BinaryTreeMidOrder_loop(rootNode); System.out.println(); System.out.println("後序遍歷(遞迴):"); tree.BinaryTreePostOrder(rootNode); System.out.println(); System.out.println("後序遍歷(非遞迴):"); tree.BinaryTreePostOrder_loop(rootNode); System.out.println(); System.out.println("層次遍歷:"); tree.BinaryTreeLevelOrder(rootNode); } }

測試結果:

遍歷前陣列:
39 21 69 6 78 21 83 53 69 52 85 
先序遍歷(遞迴):
39 21 6 53 69 78 52 85 69 21 83 
先序遍歷(非遞迴):
39 21 6 53 69 78 52 85 69 21 83 
中序遍歷(遞迴):
53 6 69 21 52 78 85 39 21 69 83 
中序遍歷(非遞迴):
53 6 69 21 52 78 85 39 21 69 83 
後序遍歷(遞迴):
53 69 6 52 85 78 21 21 83 69 39 
後序遍歷(非遞迴):
53 69 6 52 85 78 21 21 83 69 39 
層次遍歷:
39 21 69 6 78 21 83 53 69 52 85