1. 程式人生 > >輕鬆理解Java二叉樹的構建,前序中序層次遍歷,遞迴非遞迴實現

輕鬆理解Java二叉樹的構建,前序中序層次遍歷,遞迴非遞迴實現

二叉樹的構建規則:

左子樹上的值均不大於右子樹,所以在生成插入的時候,需要以下幾步

  1. 判斷根節點是否為空,不為空,則直接根節點就是插入節點
  2. 若根節點不為空,判斷值與根節點大小相比,若大於,則遞迴插入右子樹,節點變為根節點的右子樹,反之則插入左子樹。
  3. 插入的時候,若是遞迴插入,需要傳入根節點,以及值。
二叉樹實現
class TreeNode {
	int val;
	TreeNode left;
	TreeNode right;
	public TreeNode(int val) {
		this.val = val;
	}
}

插入節點功能實現:

static void insert(TreeNode tree, int val) {
    if (tree == null) {
	tree.val = val;
	} else {
		if (tree.val > val) {
			if (tree.left == null) {
				tree.left = new TreeNode(val);
			} else {
				insert(tree.left, val);
			}
		} else {
			if (tree.right == null) {
				tree.right = new TreeNode(val);
			} else {
				insert(tree.right, val);
			}
		}
	}

前序遍歷遞迴實現:

static void preOrder(TreeNode tree) {
		if (tree == null) {
			return;
		}
		System.out.println(tree.val);
		preOrder(tree.left);
		preOrder(tree.right);

	}

前序非遞迴實現:

  1. 由於前序遍歷是按照中-左-右的順序遍歷,所以用到棧這種結構,可以實現先進後出的功能,與遞迴一樣,遞迴的資料也是儲存在棧中。
  2. 首先輸出根節點資料,然後將根節點壓棧,節點變為左節點,重複直到在最底層的最左邊。
  3. 在最左邊後,彈出棧,節點變成彈出節點的右邊子樹,繼續執行步驟2
  4. 直到最底層的最右邊彈出完成,棧為空,退出迴圈。
static void preOrder2(TreeNode tree) {

		Stack<TreeNode> stack = new Stack<TreeNode>();
		TreeNode node = tree;

		while (node != null || !stack.empty()) {
			while (node != null) {
				System.out.println(node.val);
				stack.push(node);
				node = node.left;
			}
			if (!stack.empty()) {
				node = stack.pop();
				node = node.right;
			}

		}
	}

中序遍歷與前序相似,程式碼在最後展示。

層次遍歷:

  1. 層次遍歷過程是一個逐步向後的過程,有著先進行先輸出的特性,所以用佇列來實現這個過程,在java中可以通過繼承LinkedList來實現佇列。當然也可以直接用LinkedList來例項化物件。
  2. 首先還是將根節點放入隊頭
  3. 判斷佇列是否為空,如果不為空,將隊頭出隊,並列印相關值,然後判斷左右子樹是否有,若有,則入隊。
  4. 重複這個過程,直到佇列中所有值都出隊了,佇列為空,此時可以結束迴圈。
static void floor(TreeNode tree) {
		Queue<TreeNode> quene = new LinkedList<>();
		quene.add(tree);
		while (!quene.isEmpty()) {

			tree = quene.poll(); //出隊
			System.out.print(tree.val + " ");

			if (tree.left != null) {
				quene.add(tree.left); //入隊
			}
			if (tree.right != null) {
				quene.add(tree.right); 
			}

		}

	}

所有程式碼實現,main函式所在類為DF

import java.util.LinkedList;
import java.util.Queue;
import java.util.Stack;

//二叉樹實現
class TreeNode {
	int val;
	TreeNode left;
	TreeNode right;
//	建構函式
	public TreeNode(int val) {
		this.val = val;
	}
//插入節點
    static void insert(TreeNode tree, int val) {
	if (tree == null) {
	    tree.val = val;
	} else {
//如果小於根節點,放在左子樹上
	if (tree.val > val) {
	    if (tree.left == null) {
		tree.left = new TreeNode(val);
		    } else {
			insert(tree.left, val);
			}

//如果大於根節點,放在右子樹上
	    } else {
    		if (tree.right == null) {
			tree.right = new TreeNode(val);
		} else {
			insert(tree.right, val);
			}
		}
	}
    }
//前序遍歷,遞迴實現
static void preOrder(TreeNode tree) {

	if (tree == null) {
		return;
	}
//		中-左-右
	System.out.println(tree.val);
	preOrder(tree.left);
	preOrder(tree.right);

	}
//前序遍歷,非遞迴實現	
static void preOrder2(TreeNode tree) {
//		棧實現
	Stack<TreeNode> stack = new Stack<TreeNode>();
	TreeNode node = tree;

	while (node != null || !stack.empty()) {
		while (node != null) {
			System.out.println(node.val);
			stack.push(node);
//			入棧,替換根節點為左節點
			node = node.left;
		}
		if (!stack.empty()) {
//			出棧,替換根節點為右邊
			node = stack.pop();
			node = node.right;
			}

		}
	}	
	
//中序遍歷,可以排序輸出
	static void midOrder(TreeNode tree) {

		if (tree == null) {
			return;
		}
//		左-中-右
		midOrder(tree.left);
		System.out.println(tree.val);
		midOrder(tree.right);

	}
//中序遍歷非遞迴實現
	static void midOrder2(TreeNode tree) {
		Stack<TreeNode> stack = new Stack<>();

		while (tree != null || !stack.empty()) {
			while (tree != null) {
				stack.push(tree);
				tree = tree.left;
			}
			if (!stack.isEmpty()) {
				tree = stack.pop();
				System.out.println(tree.val);
				tree = tree.right;
			}

		}

	}

	
//層次遍歷
	static void floor(TreeNode tree) {
//		佇列實現或者連結串列實現
		Queue<TreeNode> quene = new LinkedList<>();
		quene.add(tree);
		while (!quene.isEmpty()) {
			tree = quene.poll();
			System.out.print(tree.val + " ");
			if (tree.left != null) {
				quene.add(tree.left);
			}
			if (tree.right != null) {
				quene.add(tree.right);
			}

		}

	}

}

public class DF {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
//二叉樹例項化
		TreeNode tree = new TreeNode(10);
		// int a[] = new int[10];
		int a[] = { 5, 20, 3, 6, 21, 25 };

		for (int i = 0; i < a.length; i++) {
			// a[i] = (int) Math.floor(Math.random() * 100);
			tree.insert(tree, a[i]);
//插入二叉樹中
		}

		tree.floor(tree);
		// tree.midOrder(tree);
		// tree.midOrder(tree);
		// tree.midOrder2(tree);


	}




層次遍歷結果:10 5 20 3 6 21 25

中序遍歷: 3 5 6 10 20 21 25

前序遍歷: 10 5 3 6 20 21 25