Binary tree
2006-08-12 02:48
204 查看
以前有学过的LinkedList和Orded Array。。这两种数据结构有利有弊。
LinkedList在插入和删除某个Node的时候只需要更改这个Node的指向下(上)一个Node的referrence就可以了,而Order Array因为在插入和删除某个Node之后必须保持整个数组的有序性,必须要做很多的Node移动,比如在一个升序的数组中要删除其中一个Node,就必须把删除掉的Node之后的Nodes向前移一格。Insert和Delete的快速是LinkedList的优势。
Orded Array在search的时候就比LinkedList快速的多。Orded Array可以通过Binary search来搜索想要的Node。search是Orded Array的优势。
而Binary Tree正是能将2者的优势集中体现的一种数据结构。
树的定义我就不说了。Binary Tree就是每个结点最多有两个子结点的树。
二叉树结点的定义:
class Node
{
int iData; // data used as key value
float fData; // other data
node leftChild; // this node's left child
node rightChild; // this node's right child
public void displayNode()
{
// method body}
}
二叉树的定义:
class Tree
{
private Node root; // the only data field in Tree
public void find(int key)
{
}
public void insert(int id, double dd)
{
}
public void delete(int id)
{
}
// various other methods
} // end class Tree
树的类只有一个root结点,其他结点可以通过leftChild,rightChild referrence来得到。。。
因为二叉树是一个有序的:leftChild<parent;rightChild>parent。。。。所以在find的时候就可以在父结点上进行比较,若要找的值大于父结点的key就去和rightChild的key再进行比较,反之和leftChild的key进行大小比较,这样一直向下找,直到找到为止
class
{
public Node find(int key)
{
Node current = root;
while(current.key!=key)
{
if(current.key<key)
current = current.leftChild;
else
current = current.rughtChild;
if(current.key==key)
return null;
}
return current;
}
}
insert方法也非常的简单,就是用find去查找,一直找到一个null的位置就插入这个Node,值得注意的就是要多设一个Node parent变量以保存上一个非空的Node。因为在找到null的时候,current已经是null了,如果没有了parent就会丢失信息,就不能把上一个非空的Node的合适的child指向inserted child。
public void insert(Node n)
{
if(root==null)
root = n;
Node current = root;
Node parent = root;
while(true)
{
parent= current;
if(n.key<current.key)
{
current = current.leftChild;
if(current==null)
{
parent.leftChild = n;
return;
}
}
else
{
current = current.rightChild;
if(current==null)
{
parent.rightChild = n;
return;
}
}
}
}
取出Binary Tree里面的结点有3种方式,分别是preOrder,inOrder,postOrder.现在就只介绍inOrder,其他两个在做代数转换的时候有用。
取出结点可以用递归来实现,递归只要分3部来完成:
不停的找这个结点的左继,一直找到叶的位置。
打印出这个Node
找这个结点的右继,一直找到爷的位置。
public void inOrder(Node current)
{
if(current!=null)
{
inOrder(current.leftChild);
displayNode(current);
inOrder(current.rightChild);
}
}
每个递归都有返回的条件,这个递归返回的条件就是当current==null的时候。
找出最大值和最小值是件非常简单的事:
public Node minimun()
{
Node current.last;
current = root;
while(current.leftChild!=null)
{
last = current;
current = current.leftChild;
}
return last;
}
找最大值就不赘述。
因为delete方法比较的复杂,下次再说吧。。。
现在来说下delete方法。。。
delete要分3种情况:
delete一个叶结点,即没有子结点的结点
delete一个只有一个子结点的结点
delete一个有两个子结点的结点
前两个都比较简单,但是第3个那个是相当的复杂。。。。。
首先是第1种情况,只需先找到要delete的Node,然后将七父结点的相应Child指向null:
public boolean delete(Node d)
{
Node parent,current;
parent=current=root;
bool isLeftChild = true;
while(current.key!=d.key)
{
parent = current;
if(d.key<current.key)
{
isLeftChild = true;
4000
current = current.leftChild;
}
else
{
isLeftChild = false;
current = current.rightChild;
}
if(current == null)
return false;
}
if(current.leftChild==null&¤t.rightChild==null)
{
if(current==root)
root =null;
else if(isLeftChild)
parent.leftChild = null;
else
parent.rightChild = null;
}
//continues....
删除有一个结点的Node也非常简单,只要将删除结点的唯一结点连到parent的相应Child上就可以了,二叉树仍将保持有序。。。
//continues....
if(current.leftChild==null)
{
if(current==root)
root = null;
else if(isLeftChild)
parent.leftChild = current.rightChild;
else
parent.rightChild = current.rightChild;
}
if(current.rightChild==null)
{
if(current==root)
root = null;
else if(isLeftChild)
parent.leftChild = current.leftChild;
else
parent.rightChild = current.leftChild;
}
如果删除的是有两个Child的Node就非常的麻烦了。。。所以在此就不说为什么(why)要这么做了,只说怎么(how)做
在开始说步骤之前,先说一下public Node getSuccessor(Node delNode)方法。。。这个方法是查找delNode的右子树中最小的一个Node.
public void getSuccessor(Node delNode)
{
Node parent,current,successor;
successor = parent = delNode;
current = delNode.rightChild;
while(current!=null)
{
parent = successor;
succesor = current;
current = current.leftChild;
}
if(successor!=delNode.rightChild)
{
parent.leftChild = successor.rightChild;
successor.rightChild = delNode.rightChild;
}
return successor;
}
//这个方法最后还判断successor是否就是delNode的右自结点,如果不是则要将successor的rightChild与parent的leftChild联系上,还要将delNode的rightChild与successor的rightChild联系上。。。
好了。。现在就来说下删除一个有两个子结点的Node。
判断要删除的结点是否是root,如果是,直接root = successor。
将successor与delNode的相关子结点联系上。
将delNode的leftChild与successor的leftChild联系上。
//continue...
Node seccssor = getSuccssor(current);
if(current==root)
root=successor;
else if(isLeftChild)
successor = parent.leftChild;
else
successor = parent.rightChild;
successor.leftChild=current.leftChild;
return true;
}
整个删除有两个结点的Node过程其实只要注意两个方面。
首先判断successor是否是delNode的rightChild;如果不是,successorParent.leftChild=successor.rightChild,successor.rightChild=delNode.rightChild;如果是,则不做任何处理。这一步被放在getSuccessor方法内
getSuccessor方法外,就是将delNode的相关子结点指向successor,successor的leftChild指向delNode的leftChild
LinkedList在插入和删除某个Node的时候只需要更改这个Node的指向下(上)一个Node的referrence就可以了,而Order Array因为在插入和删除某个Node之后必须保持整个数组的有序性,必须要做很多的Node移动,比如在一个升序的数组中要删除其中一个Node,就必须把删除掉的Node之后的Nodes向前移一格。Insert和Delete的快速是LinkedList的优势。
Orded Array在search的时候就比LinkedList快速的多。Orded Array可以通过Binary search来搜索想要的Node。search是Orded Array的优势。
而Binary Tree正是能将2者的优势集中体现的一种数据结构。
树的定义我就不说了。Binary Tree就是每个结点最多有两个子结点的树。
二叉树结点的定义:
class Node
{
int iData; // data used as key value
float fData; // other data
node leftChild; // this node's left child
node rightChild; // this node's right child
public void displayNode()
{
// method body}
}
二叉树的定义:
class Tree
{
private Node root; // the only data field in Tree
public void find(int key)
{
}
public void insert(int id, double dd)
{
}
public void delete(int id)
{
}
// various other methods
} // end class Tree
树的类只有一个root结点,其他结点可以通过leftChild,rightChild referrence来得到。。。
因为二叉树是一个有序的:leftChild<parent;rightChild>parent。。。。所以在find的时候就可以在父结点上进行比较,若要找的值大于父结点的key就去和rightChild的key再进行比较,反之和leftChild的key进行大小比较,这样一直向下找,直到找到为止
class
{
public Node find(int key)
{
Node current = root;
while(current.key!=key)
{
if(current.key<key)
current = current.leftChild;
else
current = current.rughtChild;
if(current.key==key)
return null;
}
return current;
}
}
insert方法也非常的简单,就是用find去查找,一直找到一个null的位置就插入这个Node,值得注意的就是要多设一个Node parent变量以保存上一个非空的Node。因为在找到null的时候,current已经是null了,如果没有了parent就会丢失信息,就不能把上一个非空的Node的合适的child指向inserted child。
public void insert(Node n)
{
if(root==null)
root = n;
Node current = root;
Node parent = root;
while(true)
{
parent= current;
if(n.key<current.key)
{
current = current.leftChild;
if(current==null)
{
parent.leftChild = n;
return;
}
}
else
{
current = current.rightChild;
if(current==null)
{
parent.rightChild = n;
return;
}
}
}
}
取出Binary Tree里面的结点有3种方式,分别是preOrder,inOrder,postOrder.现在就只介绍inOrder,其他两个在做代数转换的时候有用。
取出结点可以用递归来实现,递归只要分3部来完成:
不停的找这个结点的左继,一直找到叶的位置。
打印出这个Node
找这个结点的右继,一直找到爷的位置。
public void inOrder(Node current)
{
if(current!=null)
{
inOrder(current.leftChild);
displayNode(current);
inOrder(current.rightChild);
}
}
每个递归都有返回的条件,这个递归返回的条件就是当current==null的时候。
找出最大值和最小值是件非常简单的事:
public Node minimun()
{
Node current.last;
current = root;
while(current.leftChild!=null)
{
last = current;
current = current.leftChild;
}
return last;
}
找最大值就不赘述。
因为delete方法比较的复杂,下次再说吧。。。
现在来说下delete方法。。。
delete要分3种情况:
delete一个叶结点,即没有子结点的结点
delete一个只有一个子结点的结点
delete一个有两个子结点的结点
前两个都比较简单,但是第3个那个是相当的复杂。。。。。
首先是第1种情况,只需先找到要delete的Node,然后将七父结点的相应Child指向null:
public boolean delete(Node d)
{
Node parent,current;
parent=current=root;
bool isLeftChild = true;
while(current.key!=d.key)
{
parent = current;
if(d.key<current.key)
{
isLeftChild = true;
4000
current = current.leftChild;
}
else
{
isLeftChild = false;
current = current.rightChild;
}
if(current == null)
return false;
}
if(current.leftChild==null&¤t.rightChild==null)
{
if(current==root)
root =null;
else if(isLeftChild)
parent.leftChild = null;
else
parent.rightChild = null;
}
//continues....
删除有一个结点的Node也非常简单,只要将删除结点的唯一结点连到parent的相应Child上就可以了,二叉树仍将保持有序。。。
//continues....
if(current.leftChild==null)
{
if(current==root)
root = null;
else if(isLeftChild)
parent.leftChild = current.rightChild;
else
parent.rightChild = current.rightChild;
}
if(current.rightChild==null)
{
if(current==root)
root = null;
else if(isLeftChild)
parent.leftChild = current.leftChild;
else
parent.rightChild = current.leftChild;
}
如果删除的是有两个Child的Node就非常的麻烦了。。。所以在此就不说为什么(why)要这么做了,只说怎么(how)做
在开始说步骤之前,先说一下public Node getSuccessor(Node delNode)方法。。。这个方法是查找delNode的右子树中最小的一个Node.
public void getSuccessor(Node delNode)
{
Node parent,current,successor;
successor = parent = delNode;
current = delNode.rightChild;
while(current!=null)
{
parent = successor;
succesor = current;
current = current.leftChild;
}
if(successor!=delNode.rightChild)
{
parent.leftChild = successor.rightChild;
successor.rightChild = delNode.rightChild;
}
return successor;
}
//这个方法最后还判断successor是否就是delNode的右自结点,如果不是则要将successor的rightChild与parent的leftChild联系上,还要将delNode的rightChild与successor的rightChild联系上。。。
好了。。现在就来说下删除一个有两个子结点的Node。
判断要删除的结点是否是root,如果是,直接root = successor。
将successor与delNode的相关子结点联系上。
将delNode的leftChild与successor的leftChild联系上。
//continue...
Node seccssor = getSuccssor(current);
if(current==root)
root=successor;
else if(isLeftChild)
successor = parent.leftChild;
else
successor = parent.rightChild;
successor.leftChild=current.leftChild;
return true;
}
整个删除有两个结点的Node过程其实只要注意两个方面。
首先判断successor是否是delNode的rightChild;如果不是,successorParent.leftChild=successor.rightChild,successor.rightChild=delNode.rightChild;如果是,则不做任何处理。这一步被放在getSuccessor方法内
getSuccessor方法外,就是将delNode的相关子结点指向successor,successor的leftChild指向delNode的leftChild
相关文章推荐
- sicily 1156 Binary tree
- Sicily 1156. Binary tree
- 用二叉链表实现完全二叉树 (Linked Complete Binary Tree) 的实现(二)
- 线索二叉树Threaded binary tree
- poj2499--Binary Tree
- POJ 2499 Binary Tree
- Full Binary Tree
- Binary Tree Preorder Traversal
- [Leetcode] 111. Minimum Depth of Binary Tree
- Binary Tree
- Chapter 3: Binary Tree
- Invert Binary Tree -- leetcode
- Binary Tree(二叉树+思维)
- 111. Minimum Depth of Binary Tree
- [Leetcode]@python 104. Maximum Depth of Binary Tree
- Leetcode 111,104. Minimum/Maximum Depth of Binary Tree
- LeetCode *** 111. Minimum Depth of Binary Tree
- LeetCode OJ 111. Minimum Depth of Binary Tree
- LeetCode.104. Maximum Depth of Binary Tree
- Java实现简单数据结构之二叉树结构排序 binary tree