二叉树:在计算机科学中,树是一种重要的非线性数据结构,直观地看,它是数据元素(在树中称为结点)按分支关系组织起来的结构。二叉树是每个节点最多有两个子树的有序树。通常子树被称作“左子树”(left subtree)和“右子树”(right subtree)。二叉树常被用于实现二叉查找树和二叉堆。值得注意的是,二叉树不是树的特殊情形。在图论中,二叉树是一个连通的无环图,并且每一个顶点的度不大于3。有根二叉树还要满足根结点的度不大于2。有了根结点后,每个顶点定义了唯一的根结点,和最多2个子结点。然而,没有足够的信息来区分左结点和右结点。
Node节点:
package ch06BinaryTree;
public class Node {
// 关键字
private int keyData;
// 其他数据
private int otherData;
// 左子节点
private Node leftNode;
// 右子节点
private Node rightNode;
public Node(int keyData, int otherData) {
this.keyData = keyData;
this.otherData = otherData;
}
public int getKeyData() {
return keyData;
}
public void setKeyData(int keyData) {
this.keyData = keyData;
}
public int getOtherData() {
return otherData;
}
public void setOtherData(int otherData) {
this.otherData = otherData;
}
public Node getLeftNode() {
return leftNode;
}
public void setLeftNode(Node leftNode) {
this.leftNode = leftNode;
}
public Node getRightNode() {
return rightNode;
}
public void setRightNode(Node rightNode) {
this.rightNode = rightNode;
}
public void dispaly(){
System.out.println(keyData + "," + otherData);
}
}
二叉树:
package ch06BinaryTree;
public class Tree {
// 根
private Node root;
// 插入方法
public void insert(int keyData, int otherData){
Node newNode = new Node(keyData, otherData);
if(root == null)
root = newNode;
else {
Node current = root;
Node parent;
while(true){
parent = current;
if(keyData < current.getKeyData()){
current = current.getLeftNode();
if(current == null){
parent.setLeftNode(newNode);
return;
}
}else{
current = current.getRightNode();
if(current == null){
parent.setRightNode(newNode);
return;
}
}
}
}
}
// 查找方法
public Node find(int keyData){
Node current = root;
while(current.getKeyData() != keyData){
if(current.getKeyData() > keyData)
current = current.getLeftNode();
else
current = current.getRightNode();
if(current == null)
return null;
}
return current;
}
// 修改方法
public void change(int keyData, int otherData){
Node findNode = find(keyData);
findNode.setOtherData(otherData);
}
// 先序遍历
public void preOrder(Node node){
if(node != null){
node.dispaly();
preOrder(node.getLeftNode());
preOrder(node.getRightNode());
}
}
// 中序遍历
public void inOrder(Node node){
if(node != null){
inOrder(node.getLeftNode());
node.dispaly();
inOrder(node.getRightNode());
}
}
// 后续遍历
public void endOrder(Node node){
if(node != null){
endOrder(node.getLeftNode());
endOrder(node.getRightNode());
node.dispaly();
}
}
// 得到根节点
public Node getRoot(){
return root;
}
}
测试:
package ch06BinaryTree;
public class TestTree {
public static void main(String[] args) {
Tree tree = new Tree();
tree.insert(80, 80);
tree.insert(49, 49);
tree.insert(42, 42);
tree.insert(30, 30);
tree.insert(45, 45);
tree.insert(90, 90);
tree.insert(150, 150);
tree.insert(130, 130);
tree.insert(82, 82);
//tree.find(30).dispaly();
//tree.change(30, 520);
//tree.find(30).dispaly();
tree.preOrder(tree.getRoot());
System.out.println("---------");
tree.inOrder(tree.getRoot());
System.out.println("---------");
tree.endOrder(tree.getRoot());
}
}
结果:
80,80
49,49
42,42
30,30
45,45
90,90
82,82
150,150
130,130
---------
30,30
42,42
45,45
49,49
80,80
82,82
90,90
130,130
150,150
---------
30,30
45,45
42,42
49,49
82,82
130,130
150,150
90,90
80,80
以下来自百度百科:
遍历是对树的一种最基本的运算,所谓遍历二叉树,就是按一定的规则和顺序走遍二叉树的所有结点,使每一个结点都被访问一次,而且只被访问一次。由于二叉树是非线性结构,因此,
树的遍历实质上是将二叉树的各个结点转换成为一个线性序列来表示。
设L、D、R分别表示遍历左子树、访问根结点和遍历右子树, 则对一棵二叉树的遍历有三种情况:DLR(称为先根次序遍历),LDR(称为中根次序遍历),LRD (称为后根次序遍历)。
(1)
先序遍历
首先访问根,再先序遍历左(右)子树,最后先序遍历右(左)子树,C语言代码如下:
void XXBL(tree* root)
{
//Do Something with root
if (root->lchild!=NULL)
XXBL(root->lchild);
if (root->rchild!=NULL)
XXBL(root->rchild);
}
(2)
中序遍历
首先中序遍历左(右)子树,再访问根,最后中序遍历右(左)子树,C语言代码如下
void ZXBL(tree* root)
{
if(root->lchild!=NULL)
ZXBL(root->lchild);
//Do Something with root
if(root->rchild!=NULL)
ZXBL(root->rchild);
}
(3)
后序遍历
首先后序遍历左(右)子树,再后序遍历右(左)子树,最后访问根,C语言代码如下
void HXBL(tree* root)
{
if (root->lchild!=NULL)
HXBL(root->lchild);
if (root->rchild!=NULL)
HXBL(root->rchild);
//Do Something with root
}