BST即搜索二叉樹中序遍歷的三種方法(兩種遞歸,一種棧迭代)

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,放在最後測試

	}

}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章