`

数据结构之二叉树

阅读更多

一 树、二叉树和二叉查找树

1。树的概念:

递归定义:

1) 一个空结构是一个空树

2)如果t1,...,tk是分离的树,那么以t1,...,tk的根为子节点的根结构也是树

3)只有按照1,2规则产生的结构才是树

树的概念更多用于分层结构,比如数据库管理系统的分层模型。

2。二叉树(binary tree):所有节点都有两个子节点(可以为空),并且每个子节点都指明为左子节点还是右子节点

1)完全二叉数,满足第i层,有2的i-1次方个子节点此条件的二叉树

2)对于所有非空二叉树,如果它的中间子节点恰好有两个非空子女,那么叶的数目m大于中间节点的数目k,并且m=k+1

3。二叉查找树(binary search tree)

1)概念:对于树中的每个节点n,其左子节点中保存的所有数值都小于n保存的数值,右子节点保存的数值都大于n保存的数值。

2)二叉查找树可以实现更为优越的查找性能,主要实现方式有数组和链表结构,相比较而言,链表实现更为容易,因为数组实现删除和添加功能需要移动数组元素(如填补删除空位等)

 

二。二叉树的实现

首先设计一个节点(设计一个整型的二叉树,通用型通理):

此类简单明了,一个信息值,两个引用(左右子树)。

public   class  IntBSTNode  {
 
protected   int  key;

 
protected  IntBSTNode left, right;

 
public  IntBSTNode()  {
  left 
=  right  =   null ;
 }


 
public  IntBSTNode( int  el)  {
  
this (el,  null null );
 }


 
public  IntBSTNode( int  el, IntBSTNode left, IntBSTNode right)  {
  key 
=  el;
  left 
=  left;
  right 
=  right;
 }

}



由此类而实现一个完整二叉搜索树:

public   class  IntBST  {
 
protected  IntBSTNode root;

 
protected   void  visit(IntBSTNode p)  {
  System.out.print(p.key 
+   "   " );
 }


 
public  IntBST()  {
  root 
=   null ;
 }



第一步,实现二叉树的搜索,查找过程简单明了,对每一个节点将要查找的键与当前节点的数值比较,如果键小于该数,就进入节点的左子树继续比较,反之进入右子树继续此比较过程。

 

public  IntBSTNode search( int  el)  {
  
return  search(root, el);
 }


 
protected  IntBSTNode search(IntBSTNode p,  int  el)  {
  
while  (p  !=   null )
   
if  (el  ==  p.key)
    
return  p;
   
else   if  (el  <  p.key)
    p 
=  p.left;
   
else
    p 
=  p.right;
  
return   null ;
 }


此查找过程最坏情况,树成为链表O(n)=(n-1)/2,最好情况:O(n)=lg(n+1)-2。经过计算可知,一般树的平均比较次数更接近于最好情况。

第二步,实现二叉树的遍历,树的遍历就是访问树的所有节点,且每个节点被访问一次。N个节点的树有N!种不同的遍历。我们只考虑两种情况的遍历

1)广度优先遍历,是从最底层(或最高层)开始逐层向上(或向下),而在同层自左向右(或者相反)访问每一个子节点,因此共有四种情况。考虑自顶向下,自左向右的情况,利用队列实现如下:

 

public   void  breadthFirst()  {
  IntBSTNode p 
=  root;
  Queue queue 
=   new  Queue();
  
if  (p  !=   null {
   queue.enqueue(p);
   
while  ( ! queue.isEmpty())  {
    p 
=  (IntBSTNode) queue.dequeue();
    visit(p);
    
if  (p.left  !=   null )
     queue.enqueue(p.left);
    
if  (p.right  !=   null )
     queue.enqueue(p.right);
   }

  }

 }

 

2) 深度优先遍历,此种遍历关心3个任务:

V——访问一个节点

L——遍历左子树

R——遍历右子树

因此有3!=6种此类遍历,我们关心其中3种:

VLR——先序遍历树

LVR——中序遍历树

LRV——后序遍历树

如果用递归来实现这3种遍历非常容易理解,如下:

public   void  preorder()  {
  preorder(root);
 }


// 先序

protected   void  preorder(IntBSTNode p)  {
  
if  (p  !=   null {
   visit(p);
   preorder(p.left);
   preorder(p.right);
  }

 }


 
public   void  inorder()  {
  inorder(root);
 }


// 中序

protected   void  inorder(IntBSTNode p)  {
  
if  (p  !=   null {
   inorder(p.left);
   visit(p);
   inorder(p.right);
  }

 }


 
public   void  postorder()  {
  postorder(root);
 }


// 后序

protected   void  postorder(IntBSTNode p)  {
  
if  (p  !=   null {
   postorder(p.left);
   postorder(p.right);
   visit(p);
  }

 }



同样,我们知道,递归调用总可以被迭代方式取代,只不过不是这么容易理解了,在此不再列出。

第三步。插入操作,此算法很简单,不详细讲解,简单来讲就是找到合适的位置连接即可

public void insert(int el) {
        IntBSTNode p 
= root, prev = null;
        
while (p != null// find a place for inserting new node;
            prev = p;
            
if (p.key < el)
                p 
= p.right;
            
else
                p 
= p.left;
        }

        
if (root == null// tree is empty;
            root = new IntBSTNode(el);
        
else if (prev.key < el)
            prev.right 
= new IntBSTNode(el);
        
else
            prev.left 
= new IntBSTNode(el);
    }


   
第四步。节点的删除。
1)归并删除法,当被删除节点没有或者只有一个子树的时候很简单,当有两个子树存在的时候,情况稍微复杂。归并删除法就是将节点的两棵子树合并成一棵树,然后连接到节点的父节点上。归并子树的原则,寻找左子树中key最大的节点,并将其作为右子树的父节点。相反,也可以寻找右子树的key最小的节点,作为左子树的父节点。我们以第一种情况为例:

public void deleteByMerging(int el) {
        IntBSTNode tmp, node, p 
= root, prev = null;
        
while (p != null && p.key != el) // find the node p
            prev = p; // with element el;
            if (p.key < el)
                p 
= p.right;
            
else
                p 
= p.left;
        }

        node 
= p;
        
if (p != null && p.key == el) {
            
if (node.right == null// node has no right child: its left
                node = node.left; // child (if any) is attached to its parent;
            else if (node.left == null// node has no left child: its right
                node = node.right; // child is attached to its parent;
            else // be ready for merging subtrees;
                tmp = node.left; // 1. move left
                while (tmp.right != null)
                    
// 2. and then right as far as
                    tmp = tmp.right; // possible;
                tmp.right = // 3. establish the link between the
                node.right; // the rightmost node of the left
                
// subtree and the right subtree;
                node = node.left; // 4.
            }

            
if
分享到:
评论

相关推荐

    数据结构之二叉树【很好】

    数据结构之二叉树 二叉树是一种非常有用的非线性结构,它具有两个特点:非空二叉树只有一个根结点,每一个结点最多有两棵子树,且分别称为该结点的左子树与右子树。根据二叉树的概念可知,二叉树的度可以为 0(叶...

    数据结构之二叉树.rar

    本资料“数据结构之二叉树.rar”深入探讨了如何使用数组来实现二叉树的各种操作,包括插入、删除以及遍历,采用C++语言进行编程,并体现了面向对象的设计思想。 首先,我们要理解二叉树的基本概念。二叉树是由节点...

    数据结构之二叉树链表.rar

    本项目“数据结构之二叉树链表”着重探讨了如何在C++环境中实现链表形式的二叉树,以及相关的操作。 二叉树是一种非线性数据结构,每个节点最多有两个子节点,通常称为左子节点和右子节点。在数组存储的二叉树中,...

    编程数据结构之二叉树讲义

    【二叉树】是数据结构中的重要组成部分,它是一种特殊的树形结构,每个节点最多有两个子节点,分别称为左子节点和右子节点。二叉树的定义包括以下几个要点: 1. **根节点**:二叉树中只有一个特殊的节点,称为根...

    笔记7-数据结构之二叉树

    笔记7-数据结构之二叉树

    数据结构之二叉树和树(实验)

    数据结构之二叉树和树(实验)

    数据结构之二叉树实验

    /*1、建立二叉树; 2、实现该二叉树的先序遍历、中序遍历和后序遍历递归算法,输出各遍历序列; 3、统计出该二叉树中叶子结点个数; 4、实现该二叉树的中序遍历非递归算法; 5、实现交换该二叉树所有结点左右...

    数据结构之二叉树的C++实现源码

    在IT领域,数据结构是计算机科学的基础,而二叉树作为一种重要的数据结构,广泛应用于算法设计和程序开发中。本文将深入探讨如何使用C++语言实现二叉树,并结合提供的压缩包文件“PracticalTraining_Exam2_1_12_24”...

    c语言数据结构之二叉树实验

    1、参考P66建立二叉树的算法,建立图4-13(a)所示二叉树; 2、实现对该二叉树的先、中、后序遍历并输出遍历序列; 3、实现该二叉树的中序遍历非递归算法; 4、实现对该二叉树交换其左右子女的算法。

    C#语言实现数据结构之二叉树

    二叉树是一种特殊的数据结构,属于非线性的树形结构,由有限个节点组成。每个节点最多有两个子节点,分别称为左子节点和右子节点。这种特性使得二叉树在计算机科学中有着广泛的应用,如搜索、排序、文件系统等。...

    数据结构之二叉树ppt

    讲解非常详细,而且很容易理解!!!,并且在课件的后面还附加了课题,可以让你对上面的内容跟熟练。

    C语言数据结构实现二叉树的建立与遍历.cpp

    C语言数据结构实现二叉树的建立与遍历.cpp

    数据结构之二叉树(c语言描述)

    二叉树是一种特殊的树形数据结构,其中每个节点最多有两个子节点,分别称为左子节点和右子节点。这种结构在计算机科学中有着广泛的应用,例如在文件系统的目录结构、数据库索引、编译器语法分析等方面。二叉树的一个...

    数据结构之二叉树c语言代码

    一棵深度为k,且有2^k-1个结点的二叉树,称为满二叉树。这种树的特点是每一层上的结点数都是最大结点数。而在一棵二叉树中,除最后一层外,若其余层都是满的,并且或者最后一层是满的,或者是在右边缺少连续若干结点...

    合工大数据结构实验 二叉树

    本实验的主题是“二叉树”,这是数据结构中一个基础且重要的概念。二叉树是一种非线性的数据结构,由节点(或称为顶点)组成,每个节点最多有两个子节点,通常称为左子节点和右子节点。这个实验旨在帮助学生深入理解...

    数据结构之二叉树PPT学习教案.pptx

    二叉树是数据结构中的重要概念,是一种特殊的树形结构,每个节点最多有两个子节点,分别称为左子节点和右子节点。以下是对二叉树的深入解析: 1. **二叉树的基本定义**: - 二叉树可以为空,或者由一个根节点和...

    数据结构--二叉树--思维导图.pdf

    "数据结构--二叉树--思维导图" 二叉树是一种常见的数据结构,它是一种树形结构,每个节点最多有两个孩子节点,分别是左子树和右子树。二叉树可以用来存储大量数据,并且可以快速地查找、插入和删除数据。 二叉树的...

    数据结构程序之二叉树

    在IT领域,数据结构是计算机科学的基础,它研究如何有效地组织和存储数据,以便于算法的执行。...通过分析“数据结构之二叉树”这个压缩包中的内容,你将有机会亲手实现这些概念,并通过实践加深理解。

Global site tag (gtag.js) - Google Analytics