輕鬆理解Java二叉樹的構建,前序中序層次遍歷,遞迴非遞迴實現
阿新 • • 發佈:2019-01-26
二叉樹的構建規則:
左子樹上的值均不大於右子樹,所以在生成插入的時候,需要以下幾步
- 判斷根節點是否為空,不為空,則直接根節點就是插入節點
- 若根節點不為空,判斷值與根節點大小相比,若大於,則遞迴插入右子樹,節點變為根節點的右子樹,反之則插入左子樹。
- 插入的時候,若是遞迴插入,需要傳入根節點,以及值。
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);
}
前序非遞迴實現:
- 由於前序遍歷是按照中-左-右的順序遍歷,所以用到棧這種結構,可以實現先進後出的功能,與遞迴一樣,遞迴的資料也是儲存在棧中。
- 首先輸出根節點資料,然後將根節點壓棧,節點變為左節點,重複直到在最底層的最左邊。
- 在最左邊後,彈出棧,節點變成彈出節點的右邊子樹,繼續執行步驟2
- 直到最底層的最右邊彈出完成,棧為空,退出迴圈。
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; } } }
中序遍歷與前序相似,程式碼在最後展示。
層次遍歷:
- 層次遍歷過程是一個逐步向後的過程,有著先進行先輸出的特性,所以用佇列來實現這個過程,在java中可以通過繼承LinkedList來實現佇列。當然也可以直接用LinkedList來例項化物件。
- 首先還是將根節點放入隊頭
- 判斷佇列是否為空,如果不為空,將隊頭出隊,並列印相關值,然後判斷左右子樹是否有,若有,則入隊。
- 重複這個過程,直到佇列中所有值都出隊了,佇列為空,此時可以結束迴圈。
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