数据结构(java)之二叉树

1.        二叉树的逻辑结构

a)       定义:二叉树是一种非线性结构,是n个有限元素的集合,由一个根节点与两个不相交的左子树和右子树组成,当集合为空又称为空二叉树,一个元素也成为一个节点。二叉树是有序的。

b)       基本概念

                     i.            节点的度:节点下子树的个数,范围为0-2

                    ii.            叶节点:度为0的节点

                  iii.            分支节点:度不为0的节点

                  iv.            路径、路径长度:设n(i+1)n(i)的父节点,则n(1)…n(k)称为一条路径,路径长度为k-1

                    v.            节点层数:从根节点开始到叶节点,每个节点层数等于其父节点的节点层数+1,根节点的节点层数位1

                  vi.            数的深度:叶节点的最大节点层数

                 vii.            数的度:各节点度的最大值,数的度最大位2

                viii.            满二叉树:所有分支节点都有左子树和右子树且叶节点都在同一层的二叉树

                   ix.            完全二叉树:一棵深度为kn个节点的二叉树,对树中的节点按照从上到下,从左到右的顺序进行编号,树中编号为i的节点与满二叉树编号为i的节点位置相同则称为完全二叉树。特点是:叶子节点只能出现在最下层和次下层,且最下层的叶子节点集中在左边。(可以理解为在一棵深度为k满二叉树的第k层(共有2^(k-1)个节点)的最右边第一个节点开始向左去掉0(2^(k-1))0-2^(k-1)之间的奇数个节点

c)        主要性质

                     i.            非空二叉树的第k层最多有2^(k-1)个节点

                    ii.            一棵深度为k的二叉树最有有2^k-1个节点

                  iii.            对于一棵非空二叉树:叶子节点数=度为2的节点数+1

                  iv.            具有n个节点的满二叉树的深度为log(n+1),具有n个节点的完全二叉树的深度为log(n)+1

d)       二叉树的抽象数据类型

                     i.            数据元素:具有相同类型的数据集合

                    ii.            数据结构:除根节点外,每个节点都有一个直接前驱,除叶节点外,每个节点都有1-2个直接后驱

2.        二叉树的实现之顺序存储

a)       顺序存储结构:用一组连续的数组来存储二叉树数据,通常按照从左到右、从上到下的顺序进行存储,对于一般的二叉树存储在数组中,下标不能很好的反映二叉树中的节点逻辑关系,需要在数组中添加空节点,这样比较浪费存储空间。因此,一般用数组存储满二叉树或者完全二叉树比较合适。

3.        二叉树的实现之链式存储

a)       链式存储结构

                     i.            二叉链式存储结构:每个节点包括存储数据的元素,指向左子树的left和指向右子树的right,当左子树或右子树不存在时,将left或者right设置为null

                    ii.            三叉链式存储结构:相比二叉链式存储结构增加了指向父节点的parent,最常用的时二叉链式存储结构

b)       遍历

                     i.            前序遍历

publicvoid pretraverse(TreeNode<E> root) {

     while(root!=null) {

         System.out.println(root.getE());

         pretraverse(root.getLeft());

         pretraverse(root.getRight());

     }

}

                    ii.            中序遍历

publicvoid intraverse(TreeNode<E> root) {

     while(root!=null) {

         intraverse(root.getLeft());

         System.out.println(root.getE());

         intraverse(root.getRight());

     }

}

     iii.     后序遍历

publicvoid posttraverse(TreeNode<E> root) {

     while(root!=null) {

         posttraverse(root.getLeft());

         posttraverse(root.getRight());

         System.out.println(root.getE());

     }

}

      iv.     层序遍历

publicvoid leveltraverse() {

     IQueue<TreeNode<E>> queue=new MylinkQueue<>();

     TreeNode<E> temp=this.root;

     queue.enqueue(temp);

     while(!queue.isEmpty()) {

         temp=queue.dequeue();

         System.out.println(temp.getE());

         if(temp.getLeft()!=null)

            queue.enqueue(temp.getLeft());

         if(temp.getRight()!=null)

            queue.enqueue(temp.getRight());

     }

}

4.   哈夫曼树

a)   概念:也叫最优二叉树,指由根节点到各个节点的路径长度乘以节点的权值,使得带权路径之和最小。

b)   要使得带权路径之和最小,则应该使权值大的节点离根节点近,权值小的节点离根节点远

c)   步骤:

        i.     首先以每一个节点为根节点建立一棵树,形成一个集合

      ii.     选出这些树中根节点权值最小的和次最小的两棵树作为左子树和右子树,两棵子树权值和为根节点形成一棵新的树

     iii.     在原集合中删除作为左右子树的两棵树,并将新的树加入集合

      iv.     重复ii,iii直到集合中只剩下一棵树

        v.     假设每棵左子树到其父节点的边为0,右子树到其父节点的边1,按照先序遍历或者层序遍历求根节点到每个节点边的序列作为字符编码

1.        二叉树的逻辑结构

a)       定义:二叉树是一种非线性结构,是n个有限元素的集合,由一个根节点与两个不相交的左子树和右子树组成,当集合为空又称为空二叉树,一个元素也成为一个节点。二叉树是有序的。

b)       基本概念

                     i.            节点的度:节点下子树的个数,范围为0-2

                    ii.            叶节点:度为0的节点

                  iii.            分支节点:度不为0的节点

                  iv.            路径、路径长度:设n(i+1)n(i)的父节点,则n(1)…n(k)称为一条路径,路径长度为k-1

                    v.            节点层数:从根节点开始到叶节点,每个节点层数等于其父节点的节点层数+1,根节点的节点层数位1

                  vi.            数的深度:叶节点的最大节点层数

                 vii.            数的度:各节点度的最大值,数的度最大位2

                viii.            满二叉树:所有分支节点都有左子树和右子树且叶节点都在同一层的二叉树

                   ix.            完全二叉树:一棵深度为kn个节点的二叉树,对树中的节点按照从上到下,从左到右的顺序进行编号,树中编号为i的节点与满二叉树编号为i的节点位置相同则称为完全二叉树。特点是:叶子节点只能出现在最下层和次下层,且最下层的叶子节点集中在左边。(可以理解为在一棵深度为k满二叉树的第k层(共有2^(k-1)个节点)的最右边第一个节点开始向左去掉0(2^(k-1))0-2^(k-1)之间的奇数个节点

c)        主要性质

                     i.            非空二叉树的第k层最多有2^(k-1)个节点

                    ii.            一棵深度为k的二叉树最有有2^k-1个节点

                  iii.            对于一棵非空二叉树:叶子节点数=度为2的节点数+1

                  iv.            具有n个节点的满二叉树的深度为log(n+1),具有n个节点的完全二叉树的深度为log(n)+1

d)       二叉树的抽象数据类型

                     i.            数据元素:具有相同类型的数据集合

                    ii.            数据结构:除根节点外,每个节点都有一个直接前驱,除叶节点外,每个节点都有1-2个直接后驱

2.        二叉树的实现之顺序存储

a)       顺序存储结构:用一组连续的数组来存储二叉树数据,通常按照从左到右、从上到下的顺序进行存储,对于一般的二叉树存储在数组中,下标不能很好的反映二叉树中的节点逻辑关系,需要在数组中添加空节点,这样比较浪费存储空间。因此,一般用数组存储满二叉树或者完全二叉树比较合适。

3.        二叉树的实现之链式存储

a)       链式存储结构

                     i.            二叉链式存储结构:每个节点包括存储数据的元素,指向左子树的left和指向右子树的right,当左子树或右子树不存在时,将left或者right设置为null

                    ii.            三叉链式存储结构:相比二叉链式存储结构增加了指向父节点的parent,最常用的时二叉链式存储结构

b)       遍历

                     i.            前序遍历

publicvoid pretraverse(TreeNode<E> root) {

     while(root!=null) {

         System.out.println(root.getE());

         pretraverse(root.getLeft());

         pretraverse(root.getRight());

     }

}

                    ii.            中序遍历

publicvoid intraverse(TreeNode<E> root) {

     while(root!=null) {

         intraverse(root.getLeft());

         System.out.println(root.getE());

         intraverse(root.getRight());

     }

}

     iii.     后序遍历

publicvoid posttraverse(TreeNode<E> root) {

     while(root!=null) {

         posttraverse(root.getLeft());

         posttraverse(root.getRight());

         System.out.println(root.getE());

     }

}

      iv.     层序遍历

publicvoid leveltraverse() {

     IQueue<TreeNode<E>> queue=new MylinkQueue<>();

     TreeNode<E> temp=this.root;

     queue.enqueue(temp);

     while(!queue.isEmpty()) {

         temp=queue.dequeue();

         System.out.println(temp.getE());

         if(temp.getLeft()!=null)

            queue.enqueue(temp.getLeft());

         if(temp.getRight()!=null)

            queue.enqueue(temp.getRight());

     }

}

4.   哈夫曼树

a)   概念:也叫最优二叉树,指由根节点到各个节点的路径长度乘以节点的权值,使得带权路径之和最小。

b)   要使得带权路径之和最小,则应该使权值大的节点离根节点近,权值小的节点离根节点远

c)   步骤:

        i.     首先以每一个节点为根节点建立一棵树,形成一个集合

      ii.     选出这些树中根节点权值最小的和次最小的两棵树作为左子树和右子树,两棵子树权值和为根节点形成一棵新的树

     iii.     在原集合中删除作为左右子树的两棵树,并将新的树加入集合

      iv.     重复ii,iii直到集合中只剩下一棵树

        v.     假设每棵左子树到其父节点的边为0,右子树到其父节点的边1,按照先序遍历或者层序遍历求根节点到每个节点边的序列作为字符编码

猜你喜欢

转载自www.cnblogs.com/hsiaolung/p/9374428.html