數據結構-樹 學習筆記
樹結構:一種描述非線性層次關係的數據結構 ,其中重要的是樹的概念。
樹: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(' ');
}
}
}
注: