为什么使用到二叉树?
因为他通常结合了另外两种数据结构的优点。
1>在有序数组中插入数据太慢。
2>在链表中查找太慢。
用树解决问题
要是有一种数据结构,既能像链表那样快速的插入和删除,又能像有序数组那样快速的查找,那样就好了。树实现了这些特点,成为最有意思的数据结构之一。
树顶端的节点称之为“根”,一棵树只有一个根。从根到其他任何一个节点都必须有一条,而且只有一条路径。
用java代码表示树
Node 类
public class Node {
public int iData;
public double dData;
public Node leftChild; //递归定义的方法? 2011-12-1
public Node rightChild;
public void displayNode() // display ourself
{
System.out.print('{');
System.out.print(iData);
System.out.print(", ");
System.out.print(dData);
System.out.print("} ");
}
}
Tree类
查找节点:
代码:
public Node find(int key) // find node with given key
{ // (assumes non-empty tree)
Node current = root; // start at root
while(current.iData != key) // while no match,
{
if(key < current.iData) // go left?
current = current.leftChild;
else // or go right?
current = current.rightChild;
if(current == null) // if no child,
return null; // didn't find it
}
return current; // found it
} // end find()
插入一个节点:
插入一个节点 45
代码:
public void insert(int id, double dd)
{
Node newNode = new Node(); // make new node
newNode.iData = id; // insert data
newNode.dData = dd;
if(root==null) // no node in root
root = newNode;
else // root occupied
{
Node current = root; // start at root
Node parent;
while(true) // (exits internally)
{
parent = current;
if(id < current.iData) // go left?
{
current = current.leftChild;
if(current == null) // if end of the line,
{ // insert on left
parent.leftChild = newNode;
return;
}
} // end if go left
else // or go right?
{
current = current.rightChild;
if(current == null) // if end of the line
{ // insert on right
parent.rightChild = newNode;
return;
}
} // end else go right
} // end while
} // end else not root
} // end insert()
遍历树
中序遍历
1> 调用自身来遍历节点的左子树
2>访问这个节点
3> 调用自身来遍历节点的右子树
private void inOrder(Node localRoot)
{
if(localRoot != null)
{
inOrder(localRoot.leftChild);
System.out.print(localRoot.iData + " ");
inOrder(localRoot.rightChild);
}
}
删除节点:
情况1 删除没有子节点的节点
情况2 删除有一个子节点的节点
代码:
情况3 删除有两个子节点的节点
找中继后续节点
// returns node with next-highest value after delNode
// goes to right child, then right child's left descendents
private Node getSuccessor(Node delNode)
{
Node successorParent = delNode;
Node successor = delNode;
Node current = delNode.rightChild; // go to right child
while(current != null) // until no more
{ // left children,
successorParent = successor;
successor = current;
current = current.leftChild; // go to left child
}
// if successor not
if(successor != delNode.rightChild) // right child,
{ // make connections
successorParent.leftChild = successor.rightChild;
successor.rightChild = delNode.rightChild;
}
return successor;
}
后继节点是delNode的右子节点
代码:
else // two children, so replace with inorder successor
{
// get successor of node to delete (current)
Node successor = getSuccessor(current);
// connect parent of current to successor instead
if(current == root)
root = successor;
else if(isLeftChild)
parent.leftChild = successor;
else
parent.rightChild = successor;
// connect successor to current's left child
successor.leftChild = current.leftChild;
} // end else two children
// (successor cannot have a left child)
【总结】
性质1 在二叉树的第i 层上最多有2^(i-1)个结点 (i >=1)
性质2 深度为k的二叉树最多有 2^k-1 个结点 (k >=1)
l