二叉树的优势
在实际使用时会根据链表和有序数组等数据结构的不同优势进行选择。有序数组的优势在于二分查找,链表的优势在于数据项的插入和数据项的删除。但是在有序数组中插入数据就会很慢,同样在链表中查找数据项效率就很低。综合以上情况,二叉树可以利用链表和有序数组的优势,同时可以合并有序数组和链表的优势,二叉树也是一种常用的数据结构。
二叉树的构成
二叉树由节点(node)和边组成。节点分为根节点、父节点、子节点。如下图所示:
红色是根节点(root)。蓝色是子节点也是父节点,绿色的是子节点。其余的线是边。节点和链表中的节点一样都可以存放数据信息。树中的边可以用自引用表示,这种引用就是C/C++里面的指针。通常来说树是顶部小,底部大,且树呈分层结构。root节点时第0层,以此类推。二叉树最多有两个节点。
二叉树搜索
二叉树一个节点左子节点的关键字小于这个节点,右子节点关键字大于或等于这个父节点。
创建一个树节点
创建一个树节点包括左节点引用和右节点引用。
class Node
{
public int iData;
public double dData;
public Node leftNode;
public Node rightNode;
public void showNode()
{
System.out.println("{ "+iData+","+dData+" }");
}
}
创建一个树结构
创建一个树结构首先是向一个树种插入数据节点。当一棵树为null时,数据项是从树的root节点处开始插入,之后的插入顺序是根据搜索节点顺序规则进行插入。具体规则是:如果数据项比父节点的数据项要小,则插在父节点的左节点(leftNode),如果比父节点的数据项要大,则将新的node插入在父节点的右节点处(rightNode)。
private Node root;
public void insert(int iData,double dData )
{
Node newNode=new Node();
newNode.iData=iData;
newNode.dData=dData;
if(root==null)
{
root=newNode;
}
else
{
Node current=root;
Node parent;
while(true)
{
parent=current;
if(iData<current.iData)
{
current=current.leftNode;
if(current==null)
{
parent.leftNode=newNode;
return;
}
}
else
{
current=current.rightNode;
if(current==null)
{
parent.rightNode=newNode;
return;
}
}
}
}
}
以下图表示以上插入数据节点过程:
在插入节点的过程中其实也就是对tree遍历的过程,最终根据条件遍历到左右节点为null时进行添加新的节点。
查找关键字
查找关键字是数据结构一项重要操作项,在有序数组中通过二分排序效率非常高。在二叉树中的查找效率也比较高。因为二叉树的添加node的过程就是根据数据项的大小进行有序添加的,并不是毫无秩序的插入数据项。在有序的基础上进行查找关键字效率就会快很多。
public Node find(int key)
{
Node current=root;
while(current.iData!=key)
{
if(current.iData>key)
{
current=current.leftNode;
}else
{
current=current.rightNode;
}
if(current==null)
return null;
}
return current;
}
树的最值查找
树的最值查找在树中查找是比较容易的,因为从root开始查找,最小值只会出现所有父节点的左节点处,同样最大值只会出现在所有父节点的沿着右节点搜索的最底层右节点处。
public Node[] mVal()
{
Node minNode=null;
Node maxNode=null;
Node[] maxminVal=new Node[2];
Node current=root;
while(current!=null)
{
minNode=current;
current=current.leftNode;
}
maxminVal[0]=minNode;
current=root;
while(current!=null)
{
maxNode=current;
current=current.rightNode;
}
maxminVal[1]=maxNode;
return maxminVal;
}
以上是通过node数组存放两个最值,这样避免写两个方法,最后返回一个node数组。
对以上树的操作进行测试及结果:
Tree tree=new Tree();
tree.insert(3, 3.666);
tree.insert(1, 1.111);
tree.insert(2, 2.362);
tree.insert(4, 4.672);
tree.insert(5, 5.865);
tree.insert(6, 6.681);
Node node=tree.find(6);
if(node==null)
{
System.out.println("we can not find it");
}else
{
node.showNode();
}
Node[] temp=tree.mVal();
temp[0].showNode();
temp[1].showNode();
{ 6,6.681 }
{ 1,1.111 }
{ 6,6.681 }
由于第一个插入节点就是在root节点处进行插入,不管其数据项大小,该节点都是root节点,处于树的最顶层。