1. 程式人生 > >java數據結構之三叉鏈表示的二叉樹

java數據結構之三叉鏈表示的二叉樹

按層遍歷 postorder while ldl 字符串 param pub link 根節點

三叉鏈表示的二叉樹定義
所畏的三叉鏈表示是指二叉樹由指向左孩子結點、右孩子結點、父親結點【三叉】的引用(指針)數據和數據組成。
package datastructure.tree.btree;
/**
* 三叉鏈表示的二叉樹定義
* @author Administrator
*
*/
public class BinTreeNode{
private Object data; // 數據域
private BinTreeNode parent; // 父節點
private BinTreeNode lChild; // 左孩子
private BinTreeNode rChild; // 右孩子
private int height; // 以該節點為根的子樹的高度
private int size; // 該節點子孫數(包括結點本身)

public BinTreeNode() {
this(null);
}

public BinTreeNode(Object e) {
data = e;
height = 0;
size = 1;
parent = lChild = rChild = null;
}
//************ Node接口方法 *************/
/**
* 獲得結點的數據
*/
public Object getData() {
return data;
}

public void setData(Object obj) {
data = obj;
}


//-------------輔助方法,判斷當前結點位置的情況------------
/**
* 判斷是否有父親
* @return
*/
public boolean hasParent() {
return parent != null;
}

/**
* 判斷是否有左孩子
* @return 如果有左孩子結點返回true,否則返回false
*/
public boolean hasLChild() {
return null != lChild;
}

/**
* 判斷是否有右孩子
* @return
*/
public boolean hasRChild() {
return null != rChild;
}

/**
* 判斷是否為葉子結點
* @return
*/
public boolean isLeaf() {
return (!hasLChild() && !hasRChild());
}

/**
* 判斷是否為某節點的左孩子
* @return
*/
public boolean isLChild() {
return (hasParent() && this == parent.lChild);
}

/**
* 判斷是否為某結點的右孩子
* @return
*/
public boolean isRChild() {
return (hasParent()) && this == parent.rChild;
}

//-------------- 與height相關的方法-----------------
/**
* 取結點的高度,即以該節點為根的樹的高度
* @return
*/
public int getHeight() {
return height;
}

/**
* 更新當前結點及其祖先的高度
*/
public void updateHeight() {
int newH = 0;// 新高度初始化為0,高度等於左右子樹加1中的較大值
if (hasLChild())
newH = Math.max(newH, (lChild.getHeight() + 1));// //////////////???
if (hasRChild())
newH = Math.max(newH, (rChild.getHeight() + 1));// 先0和左孩子的高度加1進行比較,後左孩子高度加1和右孩子高度加1進行比較
if (newH == height)
return; // 高度沒有發生變化則直接返回
height = newH; // 否則,更新高度
if (hasParent()) // 遞歸更新祖先的高度
parent.updateHeight();
}

/********* 與size相關的方法 **********/
/**
* 取以該節點為根的樹的結點數
* @return
*/
public int getSize() {
return size;
}

/**
* 更新當前結點及祖先的子孫數
*/
public void updateSize() {
size = 1; // 初始化為1,結點本身
if (hasLChild())
size = size + lChild.getSize(); // 加上左子樹的規模
if (hasRChild())
size = size + rChild.getSize(); // 加上右子樹的規模
if (hasParent())
parent.updateSize();
}

/********** 與parent相關的方法 **********/
/**
* 取父節點
* @return
*/
public BinTreeNode getParent() {
return parent;
}

/**
* 斷開與父親的關系
*/
public void sever() {
if (!hasParent())
return;
if (isLChild())
parent.lChild = null;
else
parent.rChild = null;
parent.updateHeight(); // 更新父節點及其祖先的高度
parent.updateSize(); // 更新父節點及其祖先的規模
parent = null;
}

//********** 與lChild相關的方法 ********/
/**
* 取左孩子
* @return
*/
public BinTreeNode getLChild() {
return lChild;
}

/**
* 設置當前結點的左孩子,返回原左孩子
* @param lc
* @return
*/
public BinTreeNode setLChild(BinTreeNode lc) {
BinTreeNode oldLC = this.lChild;
if (hasLChild()) {
lChild.sever();
} // 斷開當前左孩子與結點的關系
if (null != lc) {
lc.sever(); // 判斷lc與其父節點的關系
this.lChild = lc; // 確定父子關系
lc.parent = this;
this.updateHeight(); // 更新當前結點及其祖先的高度
this.updateSize(); // 更新當前結點及其祖先的規模
}
return oldLC; // 返回原左孩子
}

//********** 與rChild相關的方法 *********/
/**
* 取右孩子
* @return
*/
public BinTreeNode getRChild() {
return rChild;
}

/**
* 設置當前結點為右孩子,返回原右孩子
* @param rc
* @return
*/
public BinTreeNode setRChild(BinTreeNode rc) {
BinTreeNode oldRC = this.rChild;
if (hasRChild()) {
rChild.sever();
} // 斷開當前右孩子與結點的關系
if (null != rc) {
rc.sever(); // 斷開rc與其父節點的關系
this.rChild = rc; // 確定父子關系
rc.parent = this;
this.updateHeight(); // 更新當前結點及其祖先的高度
this.updateSize(); // 更新當前結點及其祖先的規模
}
return oldRC; // 返回原右孩子
}
/**
* 重寫toString方法
*/
public String toString() {
return "" + data;
}

}


三叉鏈表示的二叉樹的遍歷


package datastructure.tree.btree;
import java.util.*;
import datastructure.common.Strategy;
import datastructure.queue.Queue;
import datastructure.queue.ArrayQueue;
/**
* 三叉鏈表示的二叉樹的遍歷
* @author luoweifu
*
*/
public class BinaryTreeOrder {
private int leafSize = 0;
private BinTreeNode root = null;
Strategy strategy = new StrategyEqual();

/**
* 構造函數,傳入樹的根結點
* @param node
* 樹的根結點
*/
public BinaryTreeOrder(BinTreeNode node) {
this.root = node;
Strategy strategy = new StrategyEqual();
}

public BinTreeNode getRoot() {
return root;
}

/**
* 前序遍歷
*
* @return 返回一個Iterator容器
*/
public Iterator preOrder() {
List<BinTreeNode> list = new LinkedList();
preOrderRecursion(this.root, list);
return list.iterator();
}

/**
* 遞歸定義前序遍歷
* @param rt
* 樹根結點
* @param list
* LinkedList容器
*/
private void preOrderRecursion(BinTreeNode rt, List list) {
if (null == rt)
return; // 遞歸基,空樹直接返回
list.add(rt); // 訪問根節點
preOrderRecursion(rt.getLChild(), list);// 遍歷左子樹
preOrderRecursion(rt.getRChild(), list);// 遍歷右子樹
}

/**
* 中序遍歷
*
* @return
*/
public Iterator inOrder() {
List<BinTreeNode> list = new LinkedList();
inOrderRecursion(this.root, list);
return list.iterator();
}

/**
* 遞歸定義中序遍歷
* @param rt
* 樹根結點
* @param list
* LinkedList容器
*/
private void inOrderRecursion(BinTreeNode rt, List list) {
if (null == rt)
return; // 遞歸基,空樹直接返回
inOrderRecursion(rt.getLChild(), list);// 遍歷左子樹
list.add(rt); // 訪問根節點
inOrderRecursion(rt.getRChild(), list);// 遍歷右子樹
}

/**
* 後序遍歷
* @return
*/
public Iterator postOrder() {
List<BinTreeNode> list = new LinkedList();
postOrderRecursion(this.root, list);
return list.iterator();
}

/**
* 遞歸定義後序遍歷
* @param rt
* 樹根結點
* @param list
* LinkedList容器
*/
private void postOrderRecursion(BinTreeNode rt, List list) {
if (null == rt)
return; // 遞歸基,空樹直接返回
postOrderRecursion(rt.getLChild(), list);// 遍歷左子樹
postOrderRecursion(rt.getRChild(), list);// 遍歷右子樹
list.add(rt);// 訪問根節點
}

/**
* 按層遍歷
* @return
*/
public Iterator levelOrder() {
List<BinTreeNode> list = new LinkedList();
levelOrderTraverse(this.root, list);
return list.iterator();
}

/**
* 使用隊列完成二叉樹的按層遍歷
* @param rt
* @param list
*/
private void levelOrderTraverse(BinTreeNode rt, List list) {
if (null == rt)
return;
Queue q = new ArrayQueue();
q.push(rt);// 根節點入隊列
while (!q.isEmpty()) {
BinTreeNode p = (BinTreeNode) q.deQueue(); // 取出隊首節點p並訪問
list.add(p);
if (p.hasLChild())
q.push(p.getLChild()); // 將p的非空左右孩子依次入隊列
if (p.hasRChild())
q.push(p.getRChild());
}
}

/**
* 在樹中查找元素e,並返回其所在的結點
* @param e 要查找的數據元素
* @return 返回找到的結點
*/
public BinTreeNode find(Object e) {
return searchE(root, e);
}

/**
* 遞歸查找元素e
* @param rt 樹的根
* @param e 要查找的數據元素
* @return 返回找到的結點
*/
private BinTreeNode searchE(BinTreeNode rt, Object e) {
if (null == rt)
return null;
if (strategy.equal(rt.getData(), e))
return rt;
BinTreeNode v = searchE(rt.getLChild(), e);
if (null == v)
v = searchE(rt.getRChild(), e);
return v;
}
/**
* 打印二叉樹
* @return
*/
public String printBinTree() {
StringBuilder sb = new StringBuilder();
printBinTree(root, 0, sb);
return sb.toString();
}

/**
* 打印二叉樹
* @param btree 根結點
* @param n 結點層數
* @param sb 用於保存記錄的字符串
*/
private void printBinTree(BinTreeNode btree, int n, StringBuilder sb) {
if (null == btree)
return;
printBinTree(btree.getRChild(), n + 1, sb);
for (int i = 0; i < n; i++)
sb.append("\t");
if (n >= 0)
sb.append(btree.getData() + "\n");
printBinTree(btree.getLChild(), n + 1, sb);
}

/**
* 求葉結點的個數
* @return 葉結點的個數
*/
public int sizeLeaf() {
searchLeaf(this.root);
return leafSize;
}
/**
* 葉結點的個數
* @param rt
*/
private void searchLeaf(BinTreeNode rt) {
if (null == rt)
return;
if (rt.isLeaf())
leafSize++;
else {
searchLeaf(rt.getLChild());
searchLeaf(rt.getRChild());
}
}

}


測試

package datastructure.tree.btree;
import java.util.Iterator;

public class BTreeTest2 {
// 測試功能
// 結果:所有功能都能實現,正確
public static void main(String args[]) {
//構造二叉樹
BinTreeNode roots = new BinTreeNode();
BinTreeNode node = new BinTreeNode();
roots.setData(‘A‘);
roots.setLChild(new BinTreeNode(‘B‘));
roots.setRChild(new BinTreeNode(‘C‘));
node = roots.getLChild();
node.setLChild(new BinTreeNode(‘D‘));
node.setRChild(new BinTreeNode(‘E‘));
node = roots.getRChild();
node.setLChild(new BinTreeNode(‘F‘));
BinaryTreeOrder order = new BinaryTreeOrder(roots);
//------遍歷--------
Iterator<BinTreeNode> iter1 = order.preOrder();
System.out.println("前序遍歷:");
printIterator(iter1);

Iterator<BinTreeNode> iter2 = order.inOrder();
System.out.println("中序遍歷:");
printIterator(iter2);

Iterator<BinTreeNode> iter3 = order.postOrder();
System.out.println("後序遍歷:");
printIterator(iter3);

Iterator<BinTreeNode> iter4 = order.levelOrder();
System.out.println("層次遍歷:");
printIterator(iter4);

String str = order.printBinTree();
System.out.println("打印二叉樹:\n" + str);
System.out.println("葉結點的個數:" + order.sizeLeaf());
BinTreeNode nodeone = order.find(‘E‘);
System.out.println("根結點的數據元素:" + nodeone.getData());
}
public static void printIterator(Iterator<BinTreeNode> iter) {
while(iter.hasNext()) {
System.out.print("\t" + iter.next().getData());
}
System.out.println();
}

}

結果:
前序遍歷:
A BD
E C F
中序遍歷:
D BE
A F C
後序遍歷:
D EB
F C A
層次遍歷:
A BC
D E F
打印二叉樹:
C
F
A
E
B
D

葉結點的個數:3
根結點的數據元素:E

轉載至:http://blog.csdn.net/luoweifu/article/details/9089551

java數據結構之三叉鏈表示的二叉樹