定义
书可用来描述有分支的结构,属于一种阶层性的==非线性结构==,是由一个或一个以上的节点所组成的有限集合。
1. 存在一个特殊的节点,称为树根(root).
2. 其余的节点分为n>=0 个互斥的集合,T1,T2,T…Tn,且每个集合称为子树。
树的相关名词
- 度(degree):子树的个数为该节点的度。
- 终端节点或叶子节点:没有子节点的节点,即度为0的节点。
- 非终端节点:叶子以外的节点均为非终端节点,既度不为0的节点。
- 阶层或级:树的层级。
- 高度:树的最大阶度。
- 树林:树林是由n个互斥树的集合(n>=0),移去树根即为森林。
- 祖先和子孙:祖先就是从根节点到该节点路径上所包含的全部节点,子孙就是该节点子树中的任一节点。
二叉树
一般树状结构在计算机内存中存储方式以链表(Linked List)为主。
1. 深度为K的二叉树的总节点数是2^K -1 ;
2. 对于完整二叉树而言,假设有N个节点,此二叉树的阶层h为|log2(N+1)|.
二叉树的分类
- 满二叉树,如果高度为h,树的节点数为2^h -1 ,则为满二叉树。
- 完全二叉树,二叉树的度为h,所含节点数小于2^h -1。但是节点的编号如何满二叉树一般,从左到右,由上到下的顺序一一对应。
- 歪斜树,当一个二叉树完全没有右节点或左节点时,我们把它称为左歪斜树或右歪斜树。
- 严格二叉树,如果二叉树的每个==非终端节点==均有非空的左右子树,则为严格二叉树
二叉树的存储方式
- 数组表示法
package com.cjm.mvnbook.test8.CH6;// =============== Program Description ===============
// 程序名称: CH06_01.java
// 程序目的:建立二叉树
// ===================================================
import java.io.*;
public class CH06_01
{
public static void main(String args[]) throws IOException
{
int i,level;
int data[]={6,3,5,9,7,8,4,2}; /*原始数组*/
int btree[]=new int[16];
for(i=0;i<16;i++) btree[i]=0;
System.out.print("原始数组内容: \n");
for(i=0;i<8;i++)
System.out.print("["+data[i]+"] ");
System.out.println();
for(i=0;i<8;i++) /*把原始数组中的值逐一对比*/
{
for(level=1;btree[level]!=0;) /*比较树根及数组内的值*/
{
if(data[i]>btree[level]) /*如果数组内的值大于树根,则往右子树比较*/
level=level*2+1;
else /*如果数组内的值小于或等于树根,则往左子树比较*/
level=level*2;
} /*如果子树节点的值不为0,则再与数组内的值比较一次*/
btree[level]=data[i]; /*把数组值放入二叉树*/
}
System.out.print("二叉树内容:\n");
for (i=1;i<16;i++)
System.out.print("["+btree[i]+"] ");
System.out.print("\n");
}
}
- 列表表示法
package com.cjm.mvnbook.test8.CH6;// =============== Program Description ===============
// 程序名称: CH06_02.java
// 程序目的:以链表实现二叉树
// ===================================================
import java.io.*;
//二叉树节点类声明
class TreeNode {
int value;
TreeNode left_Node;
TreeNode right_Node;
// TreeNode构造函数
public TreeNode(int value) {
this.value=value;
this.left_Node=null;
this.right_Node=null;
}
}
//二叉树类声明
class BinaryTree {
public TreeNode rootNode; //二叉树的根节点
//构造函数:利用传入一个数组的参数来建立二叉树
public BinaryTree(int[] data) {
for(int i=0;i<data.length;i++)
Add_Node_To_Tree(data[i]);
}
//将指定的值加入到二叉树中适当的节点
void Add_Node_To_Tree(int value) {
TreeNode currentNode=rootNode;
if(rootNode==null) { //建立树根
rootNode=new TreeNode(value);
return;
}
//建立二叉树
while(true) {
if (value<currentNode.value) { //在左子树
if(currentNode.left_Node==null) {
currentNode.left_Node=new TreeNode(value);
return;
}
else currentNode=currentNode.left_Node;
}
else { //在右子树
if(currentNode.right_Node==null) {
currentNode.right_Node=new TreeNode(value);
return;
}
else currentNode=currentNode.right_Node;
}
}
}
//前序便利
void inOrder(TreeNode node){
if(node != null){
inOrder(node.left_Node);
System.out.println("["+node.value+"]");
inOrder(node.right_Node);
}
}
void preOrder(TreeNode node){
if(node != null){
System.out.println("["+node.value+"]");
preOrder(node.left_Node);
preOrder(node.right_Node);
}
}
void postOrder(TreeNode node){
if(node != null){
postOrder(node.left_Node);
postOrder(node.right_Node);
System.out.println("["+node.value+"]");
}
}
}
public class CH06_02 {
//主函数
public static void main(String args[]) throws IOException {
int i;
int arr[] = {7,4,1,5,16,8,11,12,15,9,2};
BinaryTree tree = new BinaryTree(arr);
System.out.println("前序遍历的结果:\n");
tree.preOrder(tree.rootNode);
System.out.println("\n");
System.out.println("中序遍历的结果:\n");
tree.inOrder(tree.rootNode);
System.out.println("\n");
System.out.println("后序遍历的结果:\n");
tree.postOrder(tree.rootNode);
}
}
- 二叉树的遍历,记住树根的位置,遍历方式一定是从左到右
-
- 中序遍历:左子树——>树根——>右子树
-
- 前序遍历:树根——>左子树——>右子树
-
- 后序遍历:左子树——>右子树——>树根