java用三叉链表构造二叉树_java数据结构之三叉链表示的二叉树

三叉链表示的二叉树定义

所畏的三叉链表示是指二叉树由指向左孩子结点、右孩子结点、父亲结点【三叉】的引用(指针)数据和数据组成。

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 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 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 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 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 iter1 = order.preOrder();

System.out.println("前序遍历:");

printIterator(iter1);

Iterator iter2 = order.inOrder();

System.out.println("中序遍历:");

printIterator(iter2);

Iterator iter3 = order.postOrder();

System.out.println("后序遍历:");

printIterator(iter3);

Iterator 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 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

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值