數據結構學習筆記之樹結構

                                                                            數據結構-樹 學習筆記

 

 

 

 

樹結構:一種描述非線性層次關係的數據結構 ,其中重要的是樹的概念。

樹:n個數據結點的集合,在該集合中包含一個根結點。根結點之下分佈着一些互不交叉的子集合,

       這些子集合也就是根結點的子樹。

 

樹結構的基本特徵:

        在一個樹結構中,有且僅有一個結點沒有直接前驅,這個結點就是樹的根結點;

        除根結點外,其餘每個結點有且僅有一個直接前驅;

        每個結點可以有任意多個直接後繼。

 

                                                  圖1

 

 

Java代碼實現:



/**
 * 非線性存儲結構 -> 鏈表實現的二叉查找樹
 * 
 * 初始化 計算表長 獲取結點 查找結點 插入結點 刪除結點
 * 
 * @see java.util.TreeMap
 * 
 */
public class Tree<T> {

	/** 根結點 */
	private Node<T> root;

	/** 比較器 */
	private final Comparator<T> comparator;

	/** 樹的容量 */
	private int size = 0;

	/** 初始化 */
	public Tree() {
		comparator = null;
	}

	/** 初始化 */
	public Tree(Comparator<T> comparator) {
		this.comparator = comparator;
	}

	/** 初始化 */
	public Tree(Comparator<T> comparator, Collection<T> c) {
		this.comparator = comparator;
		addAll(c);
	}

	/* 添加集合中所有元素到樹 */
	private boolean addAll(Collection<T> c) {
		boolean modified = false;
		for (T t : c)
			if (add(t))
				modified = true;
		return modified;
	}

	/** 添加結點 */
	public boolean add(T t) {
		Node<T> n = root;
		if (n == null) {
			root = new Node<>(t, null);
			size++;
			return true;
		}
		Node<T> parent = null;
		int m = 0;
		Comparator<? super T> c = comparator;
		if (c != null) {
			do {
				parent = n;
				m = c.compare(n.data, t);
				if (m < 0) {
					n = n.left;
				} else if (m > 0) {
					n = n.right;
				} else {
					// 相同類型元素的處理: 不能存儲兩個相同的數據.
				}
			} while (n != null);
		} else {
			@SuppressWarnings("unchecked")
			Comparable<? super T> cc = (Comparable<? super T>) t;
			do {
				parent = n;
				m = cc.compareTo(n.data);
				if (m < 0) {
					n = n.left;
				} else if (m > 0) {
					n = n.right;
				} else {
					// 相同類型元素的處理: 不能存儲兩個相同的數據.
				}
			} while (n != null);
		}
		Node<T> e = new Node<>(t, parent);
		if (m < 0)
			parent.left = e;
		else
			parent.right = e;

		size++;
		return true;
	}

	/** 刪除結點 */
	public boolean remove(T t) {
		Node<T> n = getNode(t);
		if (n == null)
			return false;
		deleteNode(n);
		return true;
	}

	/** 樹中是否存在某個對象 */
	public boolean contains(T o) {
		return getNode(o) == null ? false : true;
	}

	/* 獲得樹結點 */
	private final Node<T> getNode(T t) {
		@SuppressWarnings("unchecked")
		Comparable<? super T> c = (Comparable<? super T>) t;
		Node<T> n = root;
		while (n != null) { // 樹的遍歷
			int m = c.compareTo(n.data);
			if (m < 0)
				n = n.left;
			else if (m > 0)
				n = n.right;
			else
				return n; // 找到存儲數據的節點
		}
		return null;
	}

	/* 刪除樹結點 */
	private final void deleteNode(Node<T> node) {
		size--;
		if (node.left != null && node.right != null) {
			Node<T> n = successor(node); // 返回後繼結點
			node.data = n.data;
			node = n;
		}

		Node<T> r = (node.left != null ? node.left : node.right);
		if (r != null) { // node.left != null
			r.parent = node.parent; // 連接節點replacement到node的parent
			if (node.parent == null) // node就是root
				root = r; // 刪除node,replacement變爲root
			else if (node == node.parent.left)
				node.parent.left = r;
			else
				node.parent.right = r;

			node.left = node.right = node.parent = null; // 刪除
		} else if (node.parent == null) { //
			root = null;
		} else { //
			if (node.parent != null) {
				if (node == node.parent.left)
					node.parent.left = null;
				else if (node == node.parent.right)
					node.parent.right = null;
				node.parent = null;
			}
		}
	}

	/* 查找後繼結點 */
	private static final <T> Node<T> successor(Node<T> node) {
		if (node == null) {
			return null;
		} else if (node.right != null) {
			Node<T> p = node.right;
			while (p.left != null)
				p = p.left;
			return p;
		} else {
			Node<T> p = node.parent;
			Node<T> c = node;
			while (p != null && c == p.right) {
				c = p;
				p = p.parent;
			}
			return p;
		}
	}

	/* 查找前任結點 */
	private static final <T> Node<T> predecessor(Node<T> node) {
		if (node == null) {
			return null;
		} else if (node.left != null) {
			Node<T> n = node.left;
			while (n.right != null)
				n = n.right;
			return n;
		} else {
			Node<T> n = node.parent;
			Node<T> c = node;
			while (n != null && c == n.left) {
				c = n;
				n = n.parent;
			}
			return n;
		}
	}

	/* 遍歷子樹 */
	String orderTree(Node<T> node) { // 使用遞歸,中序遍歷子樹.
		if (node != null) {
			orderTree(node.left);
			System.out.print(node.data + ", ");
			orderTree(node.right);
		}
		return null;
	}

	/** 二叉樹的結點 */
	private static final class Node<T> {
		
		T data; // 數據
		Node<T> parent; // 父親結點
		Node<T> left; // 左子樹(小)
		Node<T> right; // 右子樹(大)
		
		Node(T data,Node<T> parent) {
			this.data = data;
			this.parent = parent;
		}
		
		@Override
		public int hashCode() {
			return data.hashCode();
		}
		
		@Override
		public boolean equals(Object obj) {
			return data.equals(obj);
		}
		
		public String toString() {
			return data.toString();
		}
		
	}

	/** 樹迭代器 */
	final class TreeIterator implements Iterator<Node<T>> {

		Node<T> next; // 下一個
		Node<T> prev; // 上一個

		TreeIterator(Node<T> first) {
			next = first;
			prev = null;
		}

		@Override
		public boolean hasNext() {
			return next != null;
		}

		@Override
		public Node<T> next() {
			Node<T> e = next;
			if (e == null)
				throw new NoSuchElementException();
			next = successor(e);
			prev = e;
			return e;
		}

		public Node<T> prev() {
			Node<T> e = next;
			if (e == null)
				throw new NoSuchElementException();
			next = predecessor(e);
			prev = e;
			return e;
		}

	}

	/** 獲得迭代器 */
	public Iterator<Node<T>> iterator() {
		Node<T> first = root;
		while (first.left != null) //找到第一個節點,即最小值節點.
			first = first.left;
		return new TreeIterator(first);
	}

	/** 計算容量 */
	public int size() {
		return size;
	}

	/** 字符串輸出 */
	public String toString() {
		Iterator<Node<T>> i = iterator();
		if (!i.hasNext())
			return "{}";
		StringBuilder builder = new StringBuilder();
		builder.append('{');
		for (;;) {
			Node<T> e = i.next();
			builder.append(e.data);
			if (!i.hasNext())
				return builder.append('}').toString();
			builder.append(',').append(' ');
		}
	}

}

 

注:

 

發佈了163 篇原創文章 · 獲贊 23 · 訪問量 29萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章