1、Node類中建立的遞歸(Easy):
見toString和Node.class中的inOrder方法
package tree;
import java.util.ArrayList;
import java.util.Deque;
import java.util.LinkedList;
import java.util.List;
/**
* 排序二叉樹
* E extends Comparable<E>指的是
* E這個類型要實現Comparable接口,這樣方便比較大小
*@author Edward
*@date 2020年7月1日---上午11:33:51
*/
public class Tree <E extends Comparable<E>>{
// root存放根節點的引用
private Node root;
public Node getRoot() {
return root;
}
public void setRoot(Node root) {
this.root = root;
}
/*
* Node類用於描述二叉樹中的某個節點,其中,
* data用於存放數據(元素),left和right分別
* 存放其左右子樹的引用。
*/
class Node{
E data;
Node left;
Node right;
Node(E e) {
data = e;
}
public boolean append(E e) {
// 相等不用添加(排序二叉樹不允許重複元素)
if (data.compareTo(e)==0) {
return false;
}
// 如果要添加的元素比根節點元素小,則添加到左子樹
if (data.compareTo(e)>0) {
if (left==null) {
left = new Node(e);
return true;
}else {
return left.append(e);
}
}else {
if (right==null) {
right = new Node(e);
return true;
}else {
return right.append(e);
}
}
}
// 用遞歸來寫根本不需要考慮整體過程
// 只需要考慮核心的分解過程
// 是JVM中的棧做了底層實現
public void inOrder(StringBuilder sb) {
// 左
if (left!=null) {
left.inOrder(sb);
}
// 中 (本身)
sb.append(data+",");
// 右
if (right!=null) {
right.inOrder(sb);
}
}
}
/**
* 向二叉樹當中添加某個元素
* @param e 被添加的元素
* @return 添加成功,返回true
*/
public boolean add(E e) {
if (root==null) {
root = new Node(e);
return true;
}
return root.append(e);
}
public String toString(){
StringBuilder sb = new StringBuilder();
sb.append("[");
root.inOrder(sb);
sb.delete(sb.lastIndexOf(","), sb.length());
return sb.append("]").toString();
}
2、傳入root節點的簡潔遞歸(Normal)
List<E>list = new ArrayList<E>();
public List<E> inorderTraversalRecur(Node root) {
// base case
if (root==null) {
return list;
}
inorderTraversalRecur(root.left);
list.add(root.data);
inorderTraversalRecur(root.right);
return list;
}
3、棧迭代(Hard):
/**
* stack迭代中序遍歷BST
* @return 返回BST的中序遍歷集合
*/
public List<E> inorderTraversal() {
List<E>list = new ArrayList<E>();
Deque<Node>stack = new LinkedList<Node>();
while (root!=null||!stack.isEmpty()) {
// 一路向左
while (root!=null) {
stack.push(root);
root = root.left;
}
// 走到盡頭,出棧
root = stack.pop();
// 放入值
list.add(root.data);
// 向右找
root = root.right;
}
return list;
}
附測試方法:
package tree;
/**
*@author Edward
*@date 2020年7月1日---下午2:18:59
*/
public class TreeTest {
public static void main(String[] args) {
Tree<Integer>tree = new Tree<Integer>();
tree.add(88);
tree.add(66);
tree.add(120);
tree.add(55);
System.out.println(tree.getRoot());
System.out.println(tree.inorderTraversalRecur(tree.getRoot())); // 這個簡潔Recur也沒問題,只會輸出一個正確的list
System.out.println(tree.toString());
System.out.println(tree.inorderTraversal()); // 這個迭代會把root迭代成null,放在最後測試
}
}