`
Jatula
  • 浏览: 276776 次
  • 性别: Icon_minigender_1
  • 来自: 深圳
社区版块
存档分类
最新评论

二叉树

阅读更多

树的定义:树是n(n>0)个结点的有穷集合。
(1)    有且仅有一个称为根的结点;
(2)    其余结点分为m(m>=0)个互不相交的非空集合T1,T2…Tm,这些集合中的每一个都是一棵树,称为根的子树。
在树上,根结点没有直接前趋。

树形结构的术语及其含义
(1)    度:树上任一结点所拥有的子树的数目称为该结点的度。
(2)    叶子或终端结点:度为0的结点。
(3)    非终端结点或分支点:度大于0的结点。
(4)    树的度:一棵树中所有结点的度的最大值。
(5)    双亲或父结点:若树中结点A是结点B的直发前趋,则A是B的双亲或父结点。
(6)    孩子或子结点:B为A的孩子或子结点。
(7)    兄弟:父结点相同的结点互称为兄弟。
(8)    子孙:一棵树上的任何结点(不包括根结点)称为根的子孙。
(9)    祖先:若B是A的子孙则A是B的祖先。
(10)    结点的层数:从根结点开始算起,根的层数为1,其余结点的层数为其双亲的层数加1。
(11)    树的高度或深度:一棵树中所有结点层数的最大值。

二叉树

二叉树的定义:二叉树结点的有有穷集合,它或者是空集,或者同时满足下述两个条件:
(1)    有且仅有一个称为根的结点;
(2)    其余结点分为两个互不相交的集合T1、T2,T1与T2都是二叉树,并且T1与T2有顺序关系(T1在T2之前),它们分别称为根的左子树和右子树。

二叉树与树的区别
(1)    二叉树可以是空集,这种二叉树称为空二叉树。
(2)    二叉树的任一结点都有两棵子树,并且这两棵子树之间有顺序关系,位置不能交换。
(3)    二叉树上任一结点的度定义为该结点的孩子数。

二叉树有五种基本形态


满二叉树:深度为k(k>=1)且有 -1个结点的二叉树。满二叉树上各层的结点数已达到了二叉树可以容纳的最大值。
完全二叉树:如果在一棵深度为k(k>=1)的满二叉树上删去第k层上最右边的连续j(0<=j< )个结点,就得到一棵深度为k的完全正确二叉树。

二叉树的性质
(1)    二叉树第i(i>=1)层上至多有 个结点。
(2)    深度为k(k>=1)的二叉树至多有 -1个结点。
(3)    对任何二叉树,若2度结点数为 ,则叶子数 = +1。
(4)    具有n个结点的完全二叉树的深度为 。
(5)    如果将一棵有n个结点的完全二叉树按层编号,则对任一编号为i(1<=i<=n)的结点X有:
<1>若i=1,则结点X是根,若i>1则X的双亲PARENT(X)的编号为 。
<2>若2i>n,则结点X无左孩子(且无右孩子);否则,X的左孩子LCHILD(X)的编号为2i。
<3>若2i+1>n,则结点X无右孩子;否则,X的右孩子RCHILD(X)的编号为2i+1。

二叉树有两种存储结构:顺序存储结构和链式存储结构。

链式存储结构的二叉树称为二叉链表。如下:
Lchild  Data  Rchild
Data域:称为数据域,用于存储二叉树结点中的数据元素;
lchild域:称为左孩子指针域,用于存放指向本结点左孩子的指针(左指针)。Rchild域也相同。
根指针:每个二叉链表还必须有一个指向根结点的指针,该指针称为根指针。根指针具有标识二叉链表的作用,对二叉链表的访问只能从根指针开始。
注意:二叉链表中每个存储结点的每个指针域必须有一个值,这个值或者是指向该结点的一个孩子的指针,或者是空指针NULL。

typedef struct btnode *bitreptr;
Struct btnode {
    datatype data;
    bitreptr lchild, rchild;
}
bitreptr root;

 

若二叉树为空,则root=NULL。

顺序存储结构由一个一维数组构成。
存储策略:对于任何完全二叉树来说,可以采用“以编号为地址”的策略将结点存入作为顺序存储结构的一维数组。在这一存储结构中,由于一结点的存储位置(下标)也就是它的编号,故结点间的逻辑关系可通过它们下标间的数值关系确定。如:在bt中找结点F的左孩子,根据二叉树性质5,从F的下标值5可以算出其左孩子的下标值为10(2*5)。右孩子的下标值为11(2*5+1)。

由于二叉树的性质5对非完全二叉树一般不成立,因此在计算非完全二叉树结点的下标值时,首先必须将其转化为完全二叉树,可以在“残缺”位置上增设“虚结点”。各个“虚结点”在数组中用一个特殊记号“∧”表示。比较浪费空间。

二叉树的遍历:就是按某种次序系统地“访问”二叉树上的所有结点,使每个结点恰好被“访问”一次。并保证只被“访问”一次。

先根遍历
(1)    访问根结点;
(2)    先根遍历左子树;
(3)    先根遍历右子树;
中根遍历
(1)    中根遍历左子树;
(2)    访问根结点;
(3)    中根遍历右子树;
后根遍历
(1)    后根遍历左子树;
(2)    后根遍历右子树;
(3)    访问根结点;

树的存储结构
(1)    孩子链表表示法:树上的一个结点的内容(数据元素)以及指向该结点所有孩子的指针存储在一起以便于运算的实现。一个孩子链表是一个带头结点的单链表,单链表的头结点含两个域:数据域和指针域。其中,数据域用于存储结点X中的数据元素;指针域用于存放指向该单链表中第一个表结点(首结点)的指针。为了检索方便,所有头结点组织成一个数组,称为表头数组。
(2)    孩子兄弟链表表示法:包含三个域:数据域—用于存储树上结点中的数据元素;孩子域—用于存放指向本结点第一个孩子的指针;兄弟域—用于存放指向本结点下一个兄弟的指针。孩子兄弟链表的结构形式与二叉链表完全相同;但存储结点中指针的含义不同。二叉链表中存储结点的左、右指针分别指向左、右孩子;而孩子兄弟链表中存储结点的两个指针分别指向“长子”和“大弟”。
(3)    双亲表示法:树上每个结点的孩子可以有任意多个,但双新只有一个。通过指向双亲的指针而将树中所有结点组织在一起形成一种存储结构是十分简洁的。在双亲表示法下,每个存储结点由两个域组成:数据域—用于存储树上结点中的数据元素;指针域—用于指示本结点的双亲所在的存储结点。孩子结点的下标值大于其双亲结点的下标值,“弟”结点的下标值大于“兄”结点的下标值。于是若要查找任一下标值为i的结点X的子孙,只需在下标值大于i的结点中去查找。

遍历方法
先根遍历:
(1)    访问根结点;
(2)    依次先根遍历根的各个子树T1,…,Tm;
后根遍历:
(1)    依次后根遍历根的各个子树T1,…,Tm;
(2)    访问根结点。
层次遍历:
(1)    若树非空,访问根结点;
(2)    若第1,…,i(i>=1)层结点已被访问,且第i+1层结点尚未访问,则从左到右依次访问第i+1层结点。

public class BinTree {
public final static int MAX=40;
private Object data; //数据元数
private BinTree left,right; //指向左,右孩子结点的链
BinTree []elements = new BinTree[MAX];//层次遍历时保存各个节点
    int front;//层次遍历时队首
    int rear;//层次遍历时队尾
private Object data; //数据元数
private BinTree left,right; //指向左,右孩子结点的链

public BinTree()
{
}
public BinTree(Object data)
{ //构造有值结点
   this.data = data;
   left = right = null;
}
public BinTree(Object data,BinTree left,BinTree right)
{ //构造有值结点
   this.data = data;
   this.left = left;
   this.right = right;
}
public String toString()
{
   return data.toString();
}

//前序遍历二叉树
public static void preOrder(BinTree parent){ 
     if(parent == null)
      return;
     System.out.print(parent.data+" ");
     preOrder(parent.left);
     preOrder(parent.right);
}

//中序遍历二叉树
public void inOrder(BinTree parent){
   if(parent == null)
      return;
   inOrder(parent.left);
   System.out.print(parent.data+" ");
     inOrder(parent.right);
}

//后序遍历二叉树
public void postOrder(BinTree parent){
   if(parent == null)
    return;
   postOrder(parent.left);
   postOrder(parent.right);
   System.out.print(parent.data+" ");
}

// 层次遍历二叉树 
public void LayerOrder(BinTree parent)
{ 
     elements[0]=parent;
     front=0;rear=1;
   while(front<rear)
   {
    try
    {
        if(elements[front].data!=null)
        {
           System.out.print(elements[front].data + " ");
           if(elements[front].left!=null)
          elements[rear++]=elements[front].left;
           if(elements[front].right!=null)
          elements[rear++]=elements[front].right;
           front++;
        }
    }catch(Exception e){break;}
   }
}

//返回树的叶节点个数
public int leaves()
{
   if(this == null)
    return 0;
   if(left == null&&right == null)
    return 1;
   return (left == null ? 0 : left.leaves())+(right == null ? 0 : right.leaves());
}

//结果返回树的高度
public int height()
{
   int heightOfTree;
   if(this == null)
    return -1;
   int leftHeight = (left == null ? 0 : left.height());
   int rightHeight = (right == null ? 0 : right.height());
   heightOfTree = leftHeight<rightHeight?rightHeight:leftHeight;
   return 1 + heightOfTree;
}

//如果对象不在树中,结果返回-1;否则结果返回该对象在树中所处的层次,规定根节点为第一层
public int level(Object object)
{
   int levelInTree;
   if(this == null)
    return -1;
   if(object == data)
    return 1;//规定根节点为第一层
   int leftLevel = (left == null?-1:left.level(object));
   int rightLevel = (right == null?-1:right.level(object));
   if(leftLevel<0&&rightLevel<0)
    return -1;
   levelInTree = leftLevel<rightLevel?rightLevel:leftLevel;
   return 1+levelInTree;
  
}

//将树中的每个节点的孩子对换位置
public void reflect()
{
   if(this == null)
    return;
   if(left != null)
    left.reflect();
   if(right != null)
    right.reflect();
   BinTree temp = left;
   left = right;
   right = temp;
}

// 将树中的所有节点移走,并输出移走的节点
public void defoliate()
{
   if(this == null)
    return;
   //若本节点是叶节点,则将其移走
   if(left==null&&right == null)
   {
    System.out.print(this + " ");
    data = null;
    return;
   }
   //移走左子树若其存在
   if(left!=null){
    left.defoliate();
    left = null;
   }
   //移走本节点,放在中间表示中跟移走...
   innerNode += this + " ";
   data = null;
   //移走右子树若其存在
   if(right!=null){
    right.defoliate();
    right = null;
   }
}

   /**
* @param args
*/
public static void main(String[] args) {
   // TODO Auto-generated method stub
   BinTree e = new BinTree("E");
   BinTree g = new BinTree("G");
   BinTree h = new BinTree("H");
   BinTree i = new BinTree("I");
   BinTree d = new BinTree("D",null,g);
  
   BinTree f = new BinTree("F",h,i);
   BinTree b = new BinTree("B",d,e);
   BinTree c = new BinTree("C",f,null);

   BinTree tree = new BinTree("A",b,c);
  
        System.out.println("前序遍历二叉树结果: ");
        tree.preOrder(tree);
        System.out.println();
        System.out.println("中序遍历二叉树结果: ");
        tree.inOrder(tree);
        System.out.println();
        System.out.println("后序遍历二叉树结果: ");
        tree.postOrder(tree);
        System.out.println();
      System.out.println("层次遍历二叉树结果: ");
     tree.LayerOrder(tree);
     System.out.println();
        System.out.println("F所在的层次: "+tree.level("F"));
        System.out.println("这棵二叉树的高度: "+tree.height());
         System.out.println("--------------------------------------");
         tree.reflect();
          System.out.println("交换每个节点的孩子节点后......");
          System.out.println("前序遍历二叉树结果: ");
        tree.preOrder(tree);
        System.out.println();
        System.out.println("中序遍历二叉树结果: ");
        tree.inOrder(tree);
        System.out.println();
        System.out.println("后序遍历二叉树结果: ");
        tree.postOrder(tree);
        System.out.println();
      System.out.println("层次遍历二叉树结果: ");
     tree.LayerOrder(tree);
     System.out.println();
        System.out.println("F所在的层次: "+tree.level("F"));
        System.out.println("这棵二叉树的高度: "+tree.height());
}

 

分享到:
评论
2 楼 swen00 2009-08-10  
代码编译有点小问题,呵呵
 
1 楼 senbao18 2008-04-17  
非常感谢!

相关推荐

    二叉树深度_二叉树查询_二叉树深度_

    二叉树是一种在计算机科学中广泛应用的数据结构,它由节点(也称为结点)组成,每个节点最多有两个子节点,通常称为左子节点和右子节点。二叉树的深度是指从根节点到最远叶节点的最长路径上边的数目,即树的最大层数...

    二叉树演示 实现二叉树图形显示

    二叉树是一种特殊的树结构,每个节点最多只有两个子节点,通常分为左子节点和右子节点。在计算机科学中,二叉树被广泛应用于数据的组织和操作,如搜索、排序、文件系统等。本例子关注的是如何实现二叉树的图形显示,...

    根据后序二叉树序列构造二叉树_扩展二叉树

    在计算机科学领域,二叉树是一种基础的数据结构,它由结点构成,每个结点最多有两个子节点,分别称为左子节点和右子节点。在众多的二叉树操作中,根据后序遍历序列(也称为后序序列)来构造二叉树是一项常见的任务。...

    二叉树建立 二叉树基本算法的实现

    (2)先序、中序、后序遍历二叉树:递归算法。 (3)中序遍历二叉树:非递归算法(最好也能实现先序,后序非递归算法)。 (4)求二叉树的高度 。 (5)求二叉树的叶子个数。 (6)对于树中每一个元素值为x的结点...

    第六章 树和二叉树作业及答案(100分).docx

    - **答案解析**:如果一棵二叉树的中序遍历序列和后序遍历序列正好相反,那么该二叉树一定是任一结点都没有左孩子的二叉树。 #### 5. 二叉树的结点数范围 - **答案解析**:深度为k的二叉树最多有\(2^k - 1\)个结点...

    将满二叉树转化为求和二叉树_二叉树_

    在IT领域,特别是数据结构和算法的学习中,二叉树是一种重要的抽象数据类型。满二叉树是一种特殊的二叉树,其中每一层都是完全填充的,除了可能的最后一层,且最后一层的所有节点都尽可能地向左靠拢。而将满二叉树...

    二叉树的各种操作各种遍历,复制,求高度,判断是否为一棵完全二叉树以及计算用二叉树存储的表达式

    根据给定的信息,本文将详细介绍二叉树的基本概念及其在程序中的实现方法,包括二叉树的创建、遍历(前序、中序、后序)、复制、求高度、判断是否为完全二叉树以及利用二叉树进行表达式的计算等操作。 ### 一、...

    构造二叉树与遍历二叉树

    ### 构造二叉树与遍历二叉树 #### 一、二叉树的基本概念 二叉树(Binary Tree)是一种非线性数据结构,在计算机科学中被广泛应用于各种算法和程序设计中。一个二叉树由零个或多个节点组成,其中每个节点最多有两个子...

    按凹入表形式横向打印任意二叉树结构,即二叉树的根在屏幕的最左边,二叉树的左子树在屏幕的下边,二叉树的右子树在屏幕的上边。

    二叉树横向打印算法的实现 二叉树是一种基本的数据结构,在计算机科学和编程中广泛应用。本资源介绍了一种特殊的二叉树打印算法,即横向打印二叉树结构。该算法将二叉树的根节点放在屏幕的最左边,左子树在屏幕的...

    复制一棵二叉树

    ### 知识点:复制一棵二叉树 #### 一、引言 在计算机科学领域,数据结构中的二叉树是一种常见的非线性数据结构,它由节点组成,每个节点最多有两个子节点,分别称为左子节点和右子节点。复制二叉树是指创建一个与原...

    二叉树的基本运算

    建立一棵二叉树,试编程实现二叉树的如下基本操作: 1. 按先序序列构造一棵二叉链表表示的二叉树T; 2. 对这棵二叉树进行遍历:先序、中序、后序以及层次遍历,分别输出结点的遍历序列; 3. 求二叉树的深度/结点数目...

    二叉树相关算法的实验验证+判别给定二叉树是否为完全二叉树。

    1、 定义链接存储的二叉树类。 2、 实验验证如下算法的正确性、各种功能及指标: 1) 创建一棵二叉树,并对其初始化; 2)先根、中根、后根遍历二叉树; 3) 在二叉树中搜索给定结点的父结点; 4) 搜索二叉树中符合...

    二叉树的建立与遍历

    二叉树的建立与遍历 二叉树是一种重要的数据结构,它广泛应用于计算机科学和软件工程中。在这篇文章中,我们将讨论二叉树的建立和遍历,包括先序遍历、中序遍历和后序遍历。 一、数据结构的重要性 数据结构是...

    二叉树_二叉树遍历_

    1.二叉树的基本操作实现【问题描述】建立一棵二叉树,用递归方法实现二叉树的如下基本操作:(1)按先序序列构造一棵二叉链表表示的二叉树T;(2)对这棵二叉树进行遍历:先序、中序、后序以及层次遍历,分别输出...

    求二叉树最大宽度 求二叉树最大宽度 数据结构

    在探讨“求二叉树最大宽度”的数据结构问题时,我们深入分析了如何通过特定算法找到一棵二叉树中每一层节点的最大数量,这一过程涉及到了数据结构与算法设计的关键概念和技术。 ### 一、二叉树的概念 二叉树是一种...

    设计程序实现二叉树结点的类型定义和对二叉树的基本操作

    ### 二叉树基本操作知识点解析 #### 一、实验目的 在本实验中,学习者将通过实际编程练习来加深对二叉树这一数据结构的理解,并熟练掌握其基本操作。具体目标包括: 1. **熟悉二叉树结点的结构和对二叉树的基本...

    二叉树遍历实验报告

    ### 二叉树遍历实验报告知识点概览 #### 一、实验背景及目标 **实验背景:** 本次实验属于《数据结构》课程的一部分,旨在通过实际编程加深学生对二叉树这一数据结构的理解和应用能力。二叉树作为一种基本且重要的...

    画二叉树小工具dtree源码

    【标题】"画二叉树小工具dtree源码"涉及的是一个用于绘制二叉树图形的编程工具,它的核心是通过源代码实现对二叉树结构的可视化展示。二叉树是一种重要的数据结构,广泛应用于计算机科学的多个领域,如搜索、排序、...

Global site tag (gtag.js) - Google Analytics