现在的位置: 首页 > 综合 > 正文

树——二叉树

2018年02月05日 ⁄ 综合 ⁄ 共 1620字 ⁄ 字号 评论关闭

树——概述我们看到,任何树都可以表示成二叉树。二叉树和树是两个完全不同的概念,一个二叉树可以没有任何节点,树至少有一个节点。对于二叉树我们要区分左子树和右子树,而对于树来说,子树的顺序是无关紧要的。

1.二叉树定义:是有限多个结点的集合,这个集合或者是空集,或者由一个根结点和两棵互不相交的,分别成为左子树和右子树的二叉树组成。根据定义,二叉树有5种基本形态,                            如下图所示。

2.  二叉树的性质:

     1)在二叉树中,第i层的节点树最多为,i>=1。(注:说的是具体哪一层的结点数,不是全部层数的结点数)

  2)在深度为k的二叉树中,结点总数最多为,k>=1.

  3) 在任何非空的二叉树T,如果叶子结点的个数为n,而度为2的结点数m, 则 n = m + 1.


  根据以上的性质,下面我们定义满二叉树和完全二叉树:

  满二叉树:一棵深度为k且具有个结点的二叉树称为满二叉树。

 完全二叉树:完全二叉树是由满二叉树而引出来的。对于深度为K的,有N个结点的二叉树,当且仅当其每一个结点都与深度为K的满二叉树中编号从1至n的结
                         点一一对应时称之为完全二叉树。

  下图是完全二叉树的示例

 

  下图是一个满二叉树的简单示例



3. 二叉树的存储表示:

    1)数组存储表示:下图的编号方案给出了二叉树说的第一种存储表示方法。由于结点是从1到n进行编号的,因此,可以用一维数组来存储这些结点(这里不使用数组的第0个位置)


克一使用数组来表示任何二叉树,尽管在许多情况下,数组会有很多未用的空间。对于完全二叉树,由于这种存储表示不浪费任何存储空间,所以,这种存储表示是理想的。但对于倾斜二叉树(看下图)只有不到一半的数组空间得到利用。

                            

    倾斜二叉树                                                                         左边倾斜二叉树的数组存储表示

       从上图可以看出,数组空间的利用率很低,因此我们要采取另一种存储方式。

    2)链式存储表示:

       虽然顺序存储表示对完全二叉树是可以接受的,但是对于许多其他的二叉树,这种存储表示却浪费了存储空间。此外,这种存储方式存在着与其他顺序存储表示方法一样的缺点,就是在中间插入和删除结点需要移动大量的结点。

       二叉树采用链式存储可以克服上面的问题。在这种存储表示方法中,每个结点都有三个域——左儿子,数据,右儿子。Java实现如下:

class BTNode {
    private int value;
    private BTNode leftChild, rightChild;
    
    public BTNode() {
        value = 0;
        leftChild = null;
        rightChild = null;
    }
    
    public BTNode(int value, BTNode leftChild, BTNode rightChild) {
        this.value = value;
        this.leftChild = leftChild;
        this.rightChild = rightChild;
    }
    
    public BTNode(int value) {
        this(value, null, null);
    }

    public BTNode getLeftChild() {
        return leftChild;
    }

    public void setLeftChild(BTNode leftChild) {
        this.leftChild = leftChild;
    }

    public BTNode getRightChild() {
        return rightChild;
    }

    public void setRightChild(BTNode rightChild) {
        this.rightChild = rightChild;
    }

    public int getValue() {
        return value;
    }
}

虽然这种结构难于确定结点的父亲,但它对于绝大多数应用都是令人满意的。若要知道结点的父亲,只需在结点中增加一个父亲域就OK了。

     

抱歉!评论已关闭.