樹/二叉樹(哈夫曼樹/紅黑樹)筆記

1.是一種經常使用數據結構,它是非線性結構。

2.樹中任一普通節點能夠有0或者多個子節點,但只能有一個父節點。

     根節點沒有父節點, 葉子節點沒有子節點。

3.二叉樹:

    1)每一個節點最多隻能有兩個子樹的有序樹
    2)左邊的子樹稱爲左子樹
    3)右邊的子樹成爲右子樹
    4)一棵深度爲k的二叉樹,若是它包含了(2^k-1)個節點,就把這棵二叉樹稱爲滿二叉樹

4.滿二叉樹的特色:

    1)每一層上的節點數都是最大節點數,即各層爲1,2,4,8,16 .... (2^k-1)
    2)一棵有n個節點的二叉樹,按滿二叉樹的編號方式對它進行編號,若樹中全部節點和滿二叉樹1~n編號徹底一致,則稱該樹爲 徹底二叉樹
        當徹底二叉樹最後一層的全部節點都是滿的時候,這棵徹底二叉樹就變成了 滿二叉樹
    3) 二叉樹的性質
        1.二叉樹第i層上的節點數目至多爲(2^i-1)
        2.深度爲k的二叉樹,至多有(2^k-1)個節點
        3.在任何一棵二叉樹中,若是其葉子節點的數量爲n0,度爲2的子節電數量爲n2,則n0=n2+1
        4.具備n個節點的徹底二叉樹的深度爲(log2n+1)

5.要實現二叉樹這種數據結構,有如下3種選擇

    1). 順序存儲         -採用數組來記錄二叉樹的全部節點
                        採用順序存儲二叉樹會形成必定的空間浪費
                        不論是遍歷樹中節點,仍是查找樹中的節點,均可以很是高效地完成,惟一缺點就是空間浪費很大
    2). 二叉鏈表存儲        -每一個節點保留一個left,right域
                        二叉鏈表存儲的思想是讓每一個節點都能記住它的左右兩個子節點
    3). 三叉鏈表存儲         -每一個節點保留一個left,right,parent域
                        爲了克服二叉鏈表存儲方式中訪問父節點不方便的問題,能夠將二叉鏈表擴展成三叉鏈表
                        三叉鏈表存儲的思 想是讓每一個節點不只記住它的左右兩個子節點,還記住它的父節點

6.遍歷二叉樹:

    對二叉樹的遍歷過程就是將非線性結構的二叉樹中的節點排列在一個線性序列上的過程。
    1).若是採用順序結構來保存二叉樹,直接遍歷底層數組便可
    2).若是採用鏈表來保存二叉樹的節點,則有兩類遍歷方式:
         a)深度優先遍歷
            這種遍歷算法將先訪問到樹中最深層次的節點
            若是L,D,R表示左子樹,根,右子樹。習慣上老是必須先遍歷左子樹,而後遍歷右子樹,根據遍歷根節點的順序不一樣,算法能夠分爲:
                DLR: 先序遍歷
                    根-左-右
                LDR: 中序遍歷
                    左-根-右
                LRD: 後序遍歷
                    左-右-根
            由於二叉樹的定義自己就有"遞歸性",因此深度優先遍歷時能很是方便地利用遞歸來遍歷每一個節點:
                一棵非空二叉樹由樹根,左子樹,右子樹組成,依次遍歷這3部分,就能夠遍歷整個二叉樹
        b)廣度優先遍歷
            這種遍歷算法將逐層訪問到每層的節點,先訪問到根,而後訪問第二層的節點...依此類推
            也被稱爲 按層遍歷

            能夠藉助具備FIFO特徵的列隊來實現 java


package knowledge;

import java.util.ArrayDeque;


/**
 * 三叉鏈表存儲二叉樹
 * @author liam.huang@foxmail.com
 * @param <E>
 */
public class ThreeLinkBinTree<E> {

	public static class TreeNode{
		
		Object data;
		TreeNode left;
		TreeNode right;
		TreeNode parent;
		
		public TreeNode(){
			
		}
		public TreeNode(Object data){
			this.data = data;
		}
		public TreeNode(Object data, TreeNode left, TreeNode right, TreeNode parent){
			this.data = data;
			this.left = left;
			this.right = right;
			this.parent = parent;
		}
	}
	
	//根節點
	private static TreeNode rootNode;
	
	//以默認的構造器建立二叉樹
	public ThreeLinkBinTree(){
		this.rootNode = new TreeNode();
	}
	
	//指定根元素建立二叉樹
	public ThreeLinkBinTree(E data){
		this.rootNode = new TreeNode(data);
	}
	
	/**
	 * 爲指定節點添加子節點
	 * @param parent	須要添加子節點的父節點
	 * @param data		新的子節點數據
	 * @param isLeft	是否爲左節點
	 * @return			新增節點
	 */
	public TreeNode addNote(TreeNode parent, E data, boolean isLeft){
		if(parent==null){
			throw new RuntimeException(parent + "節點爲null,沒法添加子節點");
		}
		if(isLeft && parent.left!=null){
			throw new RuntimeException(parent + "節點已有左子節點,沒法添加左子節點");
		}
		if(!isLeft && parent.right!=null){
			throw new RuntimeException(parent + "節點已有右子節點,沒法添加右子節點");
		}
		
		TreeNode newNode = new TreeNode(data);
		if(isLeft){
			parent.left = newNode;
		}else{
			parent.right = newNode;
		}
		newNode.parent = parent;
		return newNode;
	}
	
	//是否爲空
	public boolean isEmpty(){
		return rootNode.data==null;
	}
	
	//返回根節點
	public TreeNode rootNode(){
		if(isEmpty()){
			throw new RuntimeException("樹爲空,沒法訪問根節點");
		}
		return rootNode;
	}
	
	//返回指定節點(非根節點)的父節點
	public E parent(TreeNode node){
		if(node==null){
			throw new RuntimeException("節點爲null,沒法訪問其父節點");
		}
		return (E) node.parent.data;
	}
	
	//返回指定節點(非葉子)的左子節點
	public E leftChild(TreeNode parent){
		if(parent==null){
			throw new RuntimeException("節點爲null, 沒法添加子節點");
		}
		return (E) (parent.left==null? null : parent.left.data);
	}
	
	public E rightChild(TreeNode parent){
		if(parent==null){
			throw new RuntimeException("節點爲null, 沒法添加子節點"); 
		}
		return (E) (parent.right==null ? null : parent.right.data);
	}
	
	//返回二叉樹的深度
	public int deep(){
		return deep(rootNode);
	}
	
	//每棵子樹的深度爲其全部子樹的最大深度+1
	private int deep(TreeNode node){
		if(node==null){
			return 0;
		}
		if(node.left==null && node.right==null){
			return 1;
		}else{
			int leftDeep = deep(node.left);
			int rightDeep = deep(node.right);
			
			int max = leftDeep>rightDeep ? leftDeep : rightDeep;
			return max+1;
		}
	}
	
	
	
	//深度優先遍歷-先序遍歷
	public List<TreeNode> preIterator(){
		return preIterator(rootNode);
	}
	private List<TreeNode> preIterator(TreeNode node){
		List<TreeNode> list = new ArrayList<TreeNode>();
		list.add(node);
		if(node.left!=null){
			list.addAll(preIterator(node.left));
		}
		if(node.right!=null){
			list.addAll(preIterator(node.right));
		}
		return list;
	}
	
	//深度優先遍歷-中序遍歷
	public List<TreeNode> inIterator(){
		return inIterator(rootNode);
	}
	private List<TreeNode> inIterator(TreeNode node) {
		List<TreeNode> list = new ArrayList<TreeNode>();
		if(node.left!=null){
			list.addAll(inIterator(node.left));
		}
		list.add(node);
		if(node.right!=null){
			list.addAll(inIterator(node.right));
		}
		return list;
	}
	
	//深度優先遍歷-後序遍歷
	public List<TreeNode> postIterator(){
		return postIterator(rootNode);
	}
	private List<TreeNode> postIterator(TreeNode node){
		List<TreeNode> list = new ArrayList<TreeNode>();
		if(node.left!=null){
			list.addAll(postIterator(node.left));
		}
		if(node.right!=null){
			list.addAll(postIterator(node.right));
		}
		list.add(node);
		return list;
	}
	
	//廣度優先遍歷
	public List<TreeNode> breadthFirst(){
		Queue<TreeNode> queue = new ArrayDeque<TreeNode>();
		List<TreeNode> list = new ArrayList<TreeNode>();
		//將根元素加入"列隊"
		if(rootNode!=null){
			queue.offer(rootNode);
		}
		while(!queue.isEmpty()){
			//將該列隊的隊尾元素添加到list中
			list.add(queue.peek());
			TreeNode p = queue.poll();
			if(p.left!=null){
				queue.offer(p.left);
			}
			if(p.right!=null){
				queue.offer(p.right);
			}
		}
		return list;
	}
	
	public static void main(String[] args){
		Queue<TreeNode> queue = new ArrayDeque<TreeNode>();
		List<TreeNode> list = new ArrayList<TreeNode>();
		//將根元素加入"列隊"
		if(rootNode!=null){
			queue.offer(rootNode);
		}
		while(!queue.isEmpty()){
			//將該列隊的隊尾元素添加到list中
			list.add(queue.peek());
			TreeNode p = queue.poll();
			if(p.left!=null){
				queue.offer(p.left);
			}
			if(p.right!=null){
				queue.offer(p.right);
			}
		}
		System.out.println(list);
		
	}
	
	
}




7.哈夫曼樹

    也被稱爲 最優二叉樹
    是一類 帶權路徑最短的二叉樹
    哈夫曼樹是二叉樹的一種應用,在信息檢索中很經常使用
    1)節點之間的路徑長度:
        從一個節點到另外一個節點之間的分支數量,稱爲兩個節點之間的路徑長度
      樹的 路徑長度
        從 根節點到樹中 每個節點的路徑長度 之和
      節點的 帶權路徑長度
        從 該節點 根節點 之間的 路徑長度與節點上權乘積
      的帶權路徑長度:
        樹中全部葉子節點的帶權路徑長度 之和
    2)帶權路徑最小的二叉樹被稱爲哈夫曼樹和最優二叉樹
     3)對於具備n個葉子節點的哈夫曼樹,一共須要(2*n-1)個節點
    4)哈夫曼編碼:
        解決 報文編碼問題

        假設須要把一個字符串"abcdabcaba"進行編碼,將它轉換成惟一的二進制碼,但要求轉換出來的二進制碼的長度最小。 node

package knowledge;

import java.util.ArrayDeque;

/**
 * 哈夫曼樹
 * @author liam.huang@foxmail.com
 */
public class HuffmanTree {
	
	public static class Node<E>{
		
		E data;
		double weight;
		Node leftChild;
		Node rightChild;
		
		public Node(E data, double weight){
			this.data = data;
			this.weight = weight;
		}
		
		public String toString(){
			return "Node[data=" + data + ", weight=" + weight + "]";
		}
	}
	
	private static Node createTree(List<Node> nodes) {
		while(nodes.size()>1){
			quickSort(nodes);
			Node left = nodes.get(nodes.size()-1);
			Node right = nodes.get(nodes.size()-2);
			Node parent = new Node(null, left.weight + right.weight);
			parent.leftChild = left;
			parent.rightChild = right;
			nodes.remove(nodes.size()-1);
			nodes.remove(nodes.size()-1);
		}
		return nodes.get(0);
	}
	
	private static void quickSort(List<Node> nodes) {
		subSort(nodes, 0, nodes.size()-1);
	}
	
	private static void subSort(List<Node> nodes, int start, int end) {
		if(start<end){
			Node base = nodes.get(start);
			int i = start;
			int j = end+1;
			while(true){
				while(i<end && nodes.get(+i).weight>=base.weight);
				while(j>start && nodes.get(--j).weight<=base.weight);
				if(i<j){
					swap(nodes, i, j);
				}else{
					break;
				}
			}
			swap(nodes, start, j);
			subSort(nodes, start, j-1);
			subSort(nodes, j+1, end);
		}
	}
	
	private static void swap(List<Node> nodes, int i, int j) {
		Node tmp;
		tmp = nodes.get(i);
		nodes.set(i, nodes.get(i));
		nodes.set(j, tmp);
	}
	
	private static List<Node> breadthFirst(Node root) {
		Queue<Node> queue = new ArrayDeque<Node>();
		List<Node> list = new ArrayList<Node>();
		if(root!=null){
			queue.offer(root);
		}
		while(!queue.isEmpty()){
			list.add(queue.peek());
			Node p = queue.poll();
			if(p.leftChild!=null){
				queue.offer(p.leftChild);
			}
			if(p.rightChild!=null){
				queue.offer(p.rightChild);
			}
		}
		return list;
	}
	
	public static void main(String[] args){
		List<Node> nodes = new ArrayList<Node>();
		nodes.add(new Node("A", 40.0));
		nodes.add(new Node("B", 8.0));
		nodes.add(new Node("C", 10.0));
		nodes.add(new Node("D", 30.0));
		nodes.add(new Node("E", 10.0));
		nodes.add(new Node("F", 2.0));
		Node root = HuffmanTree.createTree(nodes);
		System.out.println(breadthFirst(root));
	}
	
}


8.排序二叉樹

    經過它能夠很是方便地對樹中全部節點進行排序和檢索
    排序二叉樹要麼是一棵空二叉樹,要麼是具備如下性質的二叉樹
        a)若它的左子樹不空,則左子樹上全部節點的值均小於它的根節點的值
        b)若它的右子樹不空,則右子樹上全部節點的值均大於它的根節點的值
        c)它的左/右子樹也分別爲排序二叉樹

9.紅黑樹

    它是一個更高效的檢索二叉樹,所以經常用來實現關聯數組
    JDK提供的集合類TreeMap,自己就是一個紅黑樹的實現
    紅黑樹在原有的排序二叉樹上增長了如下幾個要求:
        1)每一個節點要麼是紅色,要麼是黑色
        2)根節點永遠是黑色的
        3)全部的葉節點都是空節點(null),而且是黑色的,被稱爲黑哨兵
        4)每一個紅色節點的兩個子節點都是黑色
        5)從任一節點到其子樹中每一個葉子節點的路徑都包含相同數量的黑色節點
    樹的黑色高度
        從根節點到葉子節點的路徑中,包含的黑色節點數
    對於給定的黑色高度爲N的紅黑樹,從根到葉子節點的最短路徑長度爲(N-1),最長路徑長度爲2*(N-1)
    插入操做
        a)以排序二叉樹的方法插入新節點,並將它設爲紅色
        b)進行顏色調換和樹旋轉(5種情形)        
    刪除操做
        a)以排序二叉樹的方法刪除指定節點

        b)進行顏色調換和樹旋轉,使之知足紅黑樹特徵 算法

package knowledge;

import java.util.ArrayDeque;
import java.util.ArrayList;
import java.util.List;
import java.util.Queue;



/**
 * 紅黑樹
 * @author liam.huang@foxmail.com
 */
public class RedBlackTree<T extends Comparable> {
	
	private static final boolean RED = false;
	private static final boolean BLACK = true;
	
	static class Node{
		
		Object data;
		Node parent;
		Node left;
		Node right;
		//默認節點顏色爲黑色
		boolean color = BLACK;
		
		public Node(Object data, Node parent, Node left, Node right){
			this.data = data;
			this.parent = parent;
			this.left = left;
			this.right = right;
		}
		
		public String toString(){
			return "[data=" + data + ", color=" + color + "]";
		}
		
		public boolean equals(Object obj){
			if(this==obj){
				return true;
			}
			if(obj.getClass()==Node.class){
				Node target = (Node) obj;
				return data.equals(target.data)
						&& parent==target.parent
						&& left==target.left
						&& right==target.right
						&& color==target.color;
			}
			return false;
		}
	}
	
	private Node rootNode;
	
	//兩個構造器用於建立排序二叉樹
	public RedBlackTree(){
		rootNode = null;
	}
	public RedBlackTree(T element){
		rootNode = new Node(element, null, null, null);
	}
	
	//添加節點
	public void add(T element){
		
		if(rootNode==null){
			rootNode = new Node(element, null, null, null);
		}else{
			Node current = rootNode;
			Node parent = null;
			int cmp = 0;
			do{
				parent = current;
				cmp = element.compareTo(current.data);
				//若是新節點的值大於當前節點的值
				if(cmp>0){
					//以右節點做爲當前節點
					current = current.right;
				}else{
					//若是新節點的值小於當前節點的值,以左節點做爲當前節
					current = current.left;
				}
			}while(current!=null);
			
			//建立新節點
			Node newNode = new Node(element, parent, null, null);
			
			//若是新節點的值大於父節點的值
			if(cmp>0){
				//新節點做爲父節點的右節點
				parent.right = newNode;
			}else{
				//若是新節的值小於父節點的值,新節點做爲父節點的左節點
				parent.left = newNode;
			}
			//維護紅黑樹
			fixAfterInsertion(newNode);
		}
	}
	
	//插入節點後修復紅黑樹
	private void fixAfterInsertion(Node newNode) {
		newNode.color = RED;
		
		//循環直到newNode的父節點不是根,並且newNode的父節點不是紅色
		while(newNode!=null && newNode!=rootNode && newNode.parent.color!=RED){
			
			//若是newNode的父節點是其父節點的左子節點
			if(parentOf(newNode)==leftOf(parentOf(parentOf(newNode)))){
				//獲取newNode的父節點的兄弟節點
				Node bro = rightOf(parentOf(newNode));
				//若是newNode的父親節點的兄弟節點是紅色
				if(colorOf(bro)==RED){
					//將newNode的父節點設爲黑色
					setColor(parentOf(newNode), BLACK);
					//將newNode的父節點的兄弟節點設爲黑色
					setColor(bro, BLACK);
					//將newNode的父節點的父節點設爲紅色
					setColor(parentOf(parentOf(newNode)), RED);
					newNode = parentOf(parentOf(newNode));
				}else{//若是newNode的父節點的兄弟節點是黑色
					//若是newNode是其父節點的右子節點
					if(newNode==rightOf(parentOf(newNode))){
						newNode = parentOf(newNode);
						rotateLeft(newNode);
					}
					//把newNode的父節點設爲黑色
					setColor(parentOf(newNode), BLACK);
					//把newNode的父節點的父節點設爲紅色
					setColor(parentOf(parentOf(newNode)), RED);
					rotateRight(parentOf(parentOf(newNode)));
				}
				
			}else{//若是newNode的父親節點是其父節點的右子節點
				
				//獲取newNode的父親節點的父親節點的兄弟節點
				Node bro = leftOf(parentOf(parentOf(newNode)));
				//若是newNode的父親節點的兄弟節點是紅色
				if(colorOf(bro)==RED){
					//將newNode的父節點設爲黑色
					setColor(parentOf(newNode), BLACK);
					//將newNode的父節點的兄弟節點設爲黑色
					setColor(bro, BLACK);
					//將newNode的父節點的父節點設爲紅色
					setColor(parentOf(parentOf(newNode)), RED);
					//將newNode設爲newNode的父節點的節點
					newNode = parentOf(parentOf(newNode));
				}else{//若是newNode的父節點的兄弟節點是黑色
					//若是newNode是其父節點的左子節點
					if(newNode==leftOf(parentOf(newNode))){
						//將newNode的父節點設爲newNode
						newNode = parentOf(newNode);
						rotateRight(newNode);
					}
					//把newNode的父節點設爲黑色
					setColor(parentOf(newNode), BLACK);
					//把newNode的父節點的父節點設爲紅色
					setColor(parentOf(parentOf(newNode)), RED);
					rotateLeft(parentOf(parentOf(newNode)));
				}
			}
		}
		//將根節點設爲黑色
		rootNode.color = BLACK;
	}
	
	private Node parentOf(Node node) {
		return node==null ? null : node.parent;
	}
	private Node leftOf(Node node){
		return node==null ? null : node.left;
	}
	private Node rightOf(Node node){
		return node==null ? null : node.right;
	}
	private boolean colorOf(Node node){
		return node==null? BLACK : RED;
	}
	private void setColor(Node node, boolean bv){
		if(node!=null){
			node.color = bv;
		}
	}
	
	/**
	 * 執行以下轉換
	 * node			r
	 * 	  r  	node
	 * 	q			q
	 * @param node
	 */
	public void rotateLeft(Node node){
		
		if(node!=null){
			Node rn = node.right;
			Node q = rn.left;
			
			node.right = q;
			if(q!=null){
				q.parent = node;
			}
			
			rn.parent = node.parent;
			if(node.parent==null){
				rootNode = rn;
			}else if(node.parent.left==node){
				node.parent.left = rn;
			}else{
				node.parent.right = rn;
			}
			rn.left = node;
			node.parent = rn;
		}
	}
	
	/**
	 * 執行以下轉換
	 * 		node	l
	 *  l				node
	 *  	q		q
	 * @param node
	 */
	public void rotateRight(Node node){
		
		if(node!=null){
			Node ln = node.left;
			Node q = ln.right;
			
			node.left = q;
			if(q!=null){
				q.parent = node;
			}
			
			ln.parent = node.parent;
			if(node.parent==null){
				rootNode = ln;
			}else if(node.parent.left==node){
				node.parent.left = ln;
			}else{
				node.parent.right = ln;
			}
			ln.right = node;
			node.parent = ln;
			
		}
	}
	
	//刪除節點
	public void remove(T element){
		
		//獲取要刪除的節點
		Node target = getNode(element);
		//若是被刪除的節點的左子樹/右子樹都不爲空
		if(target.left!=null && target.right!=null){
			//找到target節點中序遍歷的前一個節點
			//s用於保存target節點中的左子樹中最大的節點
			Node s = target.left;
			//搜索target節點的左子樹中最大的節點
			while(s.right!=null){
				s = s.right;
			}
			//用s節點來代替p節點
			target.data = s.data;
			target = s;
		}
		//開始修復它的替換節點,若是該替換節點不爲null
		Node replacement = target.left!=null ? target.left : target.right;
		if(replacement!=null){
			//讓replacement的parent指向target的parent
			replacement.parent = target.parent;
			//若是target的parent爲null,代表target自己就是根節點
			if(target.parent==null){
				rootNode = replacement;
			}else if(target==target.parent.left){//若是target是其父節點的左子節點
				//讓target的父節點left指向replacement
				target.parent.left = replacement;
			}else{
				//讓target的父節點right指向replacement
				target.parent.right = replacement;
			}
			//完全刪除target節點
			target.left = target.right = target.parent = null;
			if(target.color = BLACK){
				fixAfterDeletion(replacement);
			}
		}else if(target.parent==null){
			rootNode = null;
		}else{
			//target沒有子節點,把它當成虛的替換節點
			//修復紅黑樹
			if(target.color==BLACK){
				fixAfterDeletion(target);
			}
			if(target.parent!=null){
				//若是target是其父節點的左子節點
				if(target==target.parent.left){
					//
					target.parent.left = null;
				}else if(target==target.parent.right){
					target.parent.right = null;
				}
				target.parent = null;
			}
		}
		
		
	}
	
	//根據給定的值搜索節點
	private Node getNode(T element) {
		//從根節點開始搜索
		Node p = rootNode;
		while(p!=null){
			int cmp = element.compareTo(p.data);
			//若是搜索的值小於當前p節點的值
			if(cmp<0){
				//向左子樹搜索
				p = p.left;
			}else if(cmp>0){
				//向右子樹搜索
				p = p.right;
			}else{
				return p;
			}
		}
		return null;
	}
	
	//刪除節點後修復紅黑樹
	private void fixAfterDeletion(Node node) {
		
		//直到node不是根節點,且node的顏色是黑色
		while(node!=rootNode && colorOf(node)==BLACK){
			//若是node是其父節點的左子節點
			if(node==leftOf(parentOf(node))){
				//獲取node節點父節點的兄弟節點
				Node bro = rightOf(parentOf(node));
				//若是bro節點是紅色
				if(colorOf(bro)==RED){
					//將bro節點設爲黑色
					setColor(bro, BLACK);
					//將bro的父節點設爲紅色
					setColor(parentOf(node), RED);
					rotateLeft(parentOf(node));
					//再次將bro設爲node的父節點的右子節點
					bro = rightOf(parentOf(node));
				}
				//若是node的兩個子節點都是黑色
				if(colorOf(leftOf(node))==BLACK && colorOf(rightOf(bro))==BLACK){
					setColor(bro, RED);
					node = parentOf(node);
				}else{
					if(colorOf(rightOf(bro))==BLACK){
						setColor(leftOf(bro), BLACK);
						setColor(bro, RED);
						rotateRight(bro);
						bro = rightOf(parentOf(node));
					}
					setColor(bro, colorOf(parentOf(node)));
					setColor(parentOf(node), BLACK);
					setColor(rightOf(node), BLACK);
					rotateLeft(parentOf(node));
					node = rootNode;
				}
			}else{
				Node bro = leftOf(parentOf(node));
				if(colorOf(bro)==RED){
					setColor(bro, BLACK);
					setColor(parentOf(node), RED);
					rotateRight(parentOf(node));
					bro = leftOf(parentOf(node));
				}
				if(colorOf(rightOf(node))==BLACK && colorOf(leftOf(node))==BLACK){
					setColor(bro, RED);
					node = parentOf(node);
				}else{
					if(colorOf(leftOf(bro))==BLACK){
						setColor(rightOf(bro), BLACK);
						setColor(bro, RED);
						rotateLeft(bro);
						bro = leftOf(parentOf(node));
					}
					setColor(bro, colorOf(parentOf(node)));
					setColor(parentOf(node), BLACK);
					setColor(leftOf(bro), BLACK);
					rotateRight(parentOf(node));
					node = rootNode;
				}
			}
		}
		setColor(node, BLACK);
	}
	
	//實現中序遍歷
	public List<Node> inIterator(){
		return inInterator(rootNode);
	}
	private List<Node> inInterator(Node rootNode) {
		List<Node> list = new ArrayList<Node>();
		//遞歸處理左子樹
		if(rootNode.left!=null){
			list.addAll(inInterator(rootNode.left));
		}
		//處理根節點
		list.add(rootNode);
		//遞歸處理右子樹
		if(rootNode.right!=null){
			list.addAll(inInterator(rootNode.right));
		}
		return list;
	}
	
	//廣度優先遍歷
	public List<Node> breadthFirst(){
		Queue<Node> queue = new ArrayDeque<Node>();
		List<Node> list = new ArrayList<Node>();
		if(rootNode!=null){
			queue.offer(rootNode);
		}
		while(!queue.isEmpty()){
			list.add(queue.peek());
			Node p = queue.poll();
			if(p.left!=null){
				queue.offer(p.left);
			}
			if(p.right!=null){
				queue.offer(p.right);
			}
		}
		return list;
	}
	
}
相關文章
相關標籤/搜索