您的位置:首页 > 其它

二叉树的链式实现

2011-05-08 22:53 246 查看
相关术语:

平衡树,非平衡树,完全数,满树。

实现策略:

1)数组实现

这个还是非常重要的,有时间写一下,先用链来写

元素n的(从0开始按层编号)左子树编号为2n+1,右子树编号为2n+2,数学证明就略了,用这个来控制下标

2)模拟链式实现

3)链式实现

树是一种非线性结构,那么跟前不一样,必须根据你的需求来构造新的节点才能满足树中的节点特征

package Tree;

public class BinaryTreeNode {

protected Object element;
protected BinaryTreeNode left,right;

public BinaryTreeNode(Object element)//用元素来构造一个结点
{
this.element = element;
left = null;
right = null;
}

public int numChildren(){//返回结点的子树上结点的个数

int count = 0;
if(left != null)
count = 1 + left.numChildren();
if(right != null)
count = count + 1 + right.numChildren();
return count;
}

}


下面是一个实现了一些基本操作的二叉树的ADT:主要是三种遍历方式

BinaryTree

package Tree;

import java.util.Iterator;

import Queue.LinkedQueue;

public class BinaryTree implements BinaryTreeADT {

private int count;
protected BinaryTreeNode root;

//3个构造方法

public BinaryTree()
{
root = null;
count = 0;
}

public BinaryTree(Object element)
{
root = new BinaryTreeNode(element);
count = 1;
}

public BinaryTree(Object element,BinaryTree leftSubtree,BinaryTree rightSubtree)
{
root = new BinaryTreeNode(element);
count = 1;
if(leftSubtree != null)
{
count = count + leftSubtree.size();
root.left = leftSubtree.root;
}
else root.left = null;

if(rightSubtree != null)
{
count = count + rightSubtree.size();
root.right = rightSubtree.root;
}
else root.right = null;
}

//接口定义的操作

public int size() {
return count;
}

public boolean isEmpty() {
return (count == 0);
}

public void removeLeftSubtree() {
if(root.left != null)
count = count - 1 - root.left.numChildren();
root.left = null;
}

public void removeRightSubtree() {
if(root.right != null)
count = count - 1 - root.right.numChildren();
root.right = null;
}

public Object find(Object target) {
Iterator it = this.iteratorInorder();
Object result = null;

while(it.hasNext())
{
result = it.next();
if(result.equals(target))
break;
else result = null;
}
return result;
}

public boolean contains(Object element) {
if(find(element) != null)
return true;
return false;
}

public Iterator iteratorInorder() {

LinkedQueue queue = new LinkedQueue();
inorder(root,queue);//将以root为根的树按序进队
return queue.iterator();//返回队列的迭代器
}

private void inorder(BinaryTreeNode node,LinkedQueue queue){
if(node != null)
{
inorder(node.left,queue);
queue.enqueue(node.element);
inorder(node.right,queue);
}
}

public Iterator PreInorder() {
LinkedQueue queue = new LinkedQueue();
preorder(root,queue);
return queue.iterator();
}

private void preorder(BinaryTreeNode node,LinkedQueue queue){
if(node != null)
{
queue.enqueue(node.element);
preorder(node.left,queue);
preorder(node.right,queue);
}
}

public Iterator PostInorder() {
LinkedQueue queue = new LinkedQueue();
postorder(root,queue);
return queue.iterator();
}

private void postorder(BinaryTreeNode node,LinkedQueue queue){
if(node != null)
{
postorder(node.left,queue);
postorder(node.right,queue);
queue.enqueue(node.element);
}
}

//直接写一个遍历的方法,不用迭代器也行
//public static void previsit(BinaryTreeNode node){
//if(node != null)
//{
//System.out.println(node.element);
//previsit(node.left);
//previsit(node.right);
//}

//}

public static void main(String[] args) {

BinaryTree  tree3 = new BinaryTree (3);
BinaryTree  tree4 = new BinaryTree (4);
BinaryTree tree2 = new BinaryTree(2,tree3,tree4);

BinaryTree  tree7 = new BinaryTree (7);
BinaryTree  tree6 = new BinaryTree (6,tree7,null);

BinaryTree  tree5 = new BinaryTree (5,null,tree6);

BinaryTree  tree1 = new BinaryTree (1,tree2,tree5);

System.out.println("树的大小是: " + tree1.size());
System.out.println("树为空吗?: " + tree1.isEmpty());

//previsit(tree1.root);

System.out.println("\n中序遍历结果为: ");
Iterator it = tree1.iteratorInorder();
while(it.hasNext())
System.out.print(it.next() + " ");

System.out.println("\n前序遍历结果为: ");
it = tree1.PreInorder();
while(it.hasNext())
System.out.print(it.next() + " ");

System.out.println("\n后序遍历结果为: ");
it = tree1.PostInorder();
while(it.hasNext())
System.out.print(it.next() + " ");

System.out.println("\n\n" + tree1.find(0));
System.out.println("包含元素6吗?: " + tree1.contains(6));
System.out.println("包含元素8吗?: " + tree1.contains(8));

tree1.removeLeftSubtree();
System.out.println("\n删除左子树后中序遍历结果为: ");
it = tree1.iteratorInorder();
while(it.hasNext())
System.out.print(it.next() + " ");

}

}


你会发现,并没有去实现add和delete操作,因为在具体的应用需求之前,并不知道该怎么去添加和删除,它不像线性结构,添加和删除后是要调整树的形状的。

由于没有写一个addleft,addright方法,构造一个树来测试显得很冗长,在main方法前面好多行,构造了下面的二叉树:



结果如下:

树的大小是: 7
树为空吗?: false

中序遍历结果为:
3 2 4 1 5 7 6
前序遍历结果为:
1 2 3 4 5 6 7
后序遍历结果为:
3 4 2 7 6 5 1

null
包含元素6吗?: true
包含元素8吗?: false

删除左子树后中序遍历结果为:
1 5 7 6
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: