《数据结构与算法分析》第四章--树 (1)

4.1 预备知识

定义:

  树的递归定义:一棵树是一些节点的集合,这个集合若为空集;否则由一个根结点以及该节点的0个或者若干个非空子树组成,这些子树都与该根节点有边连接。

  树叶:没有子节点的节点。

  兄弟(Siblings):有相同父亲节点的节点。

  节点n1到nj的路径:一个节点 序列:n1,n2...,nj。

  路径的长:路径上的边数。

  节点ni的深度:根节点到ni的唯一路径的长。根节点深度为0。

  节点ni的高度:该节点ni到叶子节点的最长路径。树的高:根节点的高度。

4.1.1 树的实现

左孩子右兄弟链表法:链表中增加两个附加元素一个记录其最左边的孩子,另一个记录其右边的兄弟。(树中子节点不分左右,这里为了存储方便)

//左孩子右兄弟节点表示
class TreeNode<E>
{
    E data;
    private TreeNode<E> firstChild;
    private TreeNode<E> nextSibling;
    public void set_firstChild(TreeNode<E> t){
        firstChild=t;
    }
    public TreeNode<E> get_firstChild(){
        return firstChild;
    }
    public void set_nextSiblling(TreeNode<E> t){
        nextSibling=t;
    }
    public TreeNode<E> get_nextSiblling(TreeNode<E> t){
        return nextSibling;
    }
    public TreeNode(TreeNode<E> firstChild,TreeNode<E> nextSibling){
        this.firstChild=firstChild;
        this.nextSibling=nextSibling;
    }
}

  这里树上只给了节点的数据表示,没有给出树上的操作,这里我给该树ADT增加操作;

树ADT设计:

 1 ADT Tree{
 2   数据对象Data:D是具有左孩子右兄弟和数据的相同类型数据元素集合;
 3   基本操作P:
 4       InitTree(TreeNode T)
 5             操作结果:构造空树T;
 6       CreateTree(TreeNode T,definition)
 7              初始条件:definition给出树T的定义;
 8              操作结果:按definition构造树
 9       TreeEmpty()
10              操作结果:返回是否为空;
11       Add(TreeNode k,TreeNode x)
12             初始条件:k是树中的一个节点;
13             操作结果:x作为k的子节点被添加进去
14       ShowPreOrder()
15            操作结果:输出树的结构;
16
17 }        

树的遍历的简单应用:

  先序遍历:采用递归的方法,在根节点对子树递归调用先序遍历方法;递归终止条件:输入节点为叶子节点,则打印并且停止;否则打印并递归向下;

class Tree<E>
{
    private static class TreeNode<E>
    {
        E data;
        TreeNode<E> firstchild;
        TreeNode<E> nextSibling;
        TreeNode(E d)
        {
            data=d;
            firstchild=null;
            nextSibling=null;
        }
    }
    private TreeNode<E> root=null;
    public TreeNode<E> getroot(){
        return root;
    }
    Tree()
    {
    }
    Tree(E root)
    {
        this.root=new TreeNode<E>(root);
    }
    public boolean treeEmpty()
    {
        return root==null;
    }
    public TreeNode<E> find(int d,int w)
    {
        if(d<0||w<0)
            throw new NullPointerException("d<0");
        if (d==0)
        {
            return root;
        }
        TreeNode<E> p=root;
        while(d!=0){
            p=p.firstchild;
            d--;
        }
        while(w!=0)
        {
            p=p.nextSibling;
            w--;
        }
        return p;
    }
    public boolean addChild(int d,int w,E x)
    {
        return addChild(find(d,w),new TreeNode<E>(x));
    }
    public boolean addChild(TreeNode<E> k,E x)
    {
        return addChild(k,new TreeNode<E>(x));
    }
    public boolean addChild(TreeNode<E> k,TreeNode<E> x)
    {
        if(k.firstchild==null)
        {
            k.firstchild=x;
            return true;
        }
        TreeNode<E> p=k.firstchild;
        while(p.nextSibling!=null)
        {
            p=p.nextSibling;
        }
        p.nextSibling = x;
        return true;
    }
    public void printPreOrder(int depth,TreeNode<E> r)
    {
        String nbsp="";
        for(int i=0;i<depth;i++){
            nbsp=nbsp+"   ";
        }
        System.out.println(nbsp+(String) r.data);
        TreeNode<E> q=r.firstchild;
        if(q!=null)
        {
            while(q.nextSibling!=null){
                printPreOrder(depth+1,q);
                q=q.nextSibling;
            }
            printPreOrder(depth+1,q);
        }
    }
}

效果图:

时间: 2024-08-04 22:45:41

《数据结构与算法分析》第四章--树 (1)的相关文章

《数据结构与算法分析:C语言描述》复习——第四章“树”——AVL树

2014.06.15 16:22 简介: AVL树是一种高度平衡的二叉搜索树,其命名源自于联合发明算法的三位科学家的名字的首字母.此处“平衡”的定义是:任意节点的左右子树的高度相差不超过1.有了这个平衡的性质,使得AVL树的高度H总是接近log(N),因此各种增删改查的操作的复杂度能够保证在对数级别.没有bad case是AVL树与普通的二叉搜索树的最大区别.为了实现平衡性质,我们需要记录每个节点的高度(或者平衡因子)来检测不平衡的情况.为了修正高度不平衡,需要用到“旋转”的方法,分为单旋转和双

数据结构与算法分析-第3章

.title { text-align: center; margin-bottom: .2em } .subtitle { text-align: center; font-size: medium; font-weight: bold; margin-top: 0 } .todo { font-family: monospace; color: red } .done { font-family: monospace; color: green } .priority { font-fami

数据结构学习之第7章 树和二叉树

数据结构学习之第7章 树和二叉树 0x7.1.1 树的基本概念 ?1.树的定义 ? 树是由n(n>=0)个结点(或元素)组成的有限集合(记为T) ? 如果n>0,这n个结点中有且仅有一个结点作为树的根结点,简称为根,其余结点可分为m(m>=0)个互不相交的有限集\[T_{1}T_{2}\cdots T_{m}\],其中每个子集又是一棵符合定义的子树,称为根结点的子树. 知识点:由树的定义我们可以看出来树的结构是递归的 ?2.树的逻辑表示法 ? 1.树形表示法 ? 2.文氏图表示法 ? 3

数据结构和算法分析(11)树的简介

    对于大量的数据,链表的线性访问时间太慢,不宜使用.我们介绍一种简单的数据结构,其大部分操作的平均时间为O(log N).     (1)学习目标: 我们将要涉及到的数据结构叫做二叉查找树(binary search tree). 我们将要了解如下内容: 1.了解树是如何用于实现几个流行的操作系统中的文件系统的; 2.看到树如何能够用来计算算术表达式的值; 3.如何指出利用树支持以O(log N)平均时间进行的各种搜索操作,以及如何细化得到最坏情况时间界O(log N).我们还将讨论当数据

数据结构与算法分析(四)——不相交集

基本介绍 一个集合S,集合中一个元素a.a的等价类是S的一个子集,该子集包含所有与a有关系的元素. 等价类形成是对S的一个划分且S中的每一个成员恰好出现在一个等价类中.这样,判断a与b是否有关系, 只需要判断a与b是否在一个等价类中即可. 对于集合S划分,取任意两个等价类,Si与Sj,如果Si∩Sj = ∅,则称这些集合不相交. 对于不相交集,有两种操作,Union/Find操作.Find操作找包含给定元素的集合(等价类)名字. Union把两个等价类合并成一个新的等价类. 数据结构:采用树来表

数据结构期末复习第六章树和二叉树

知识点: 先序遍历二叉树规则:根-左-右 1.访问根结点 2.先序遍历左子树 3.先序遍历右子树 中序遍历二叉树规则:左-根-右 1.先中序遍历左子树 2.再访问根节点 3.最后访问中序遍历右子树 后序遍历二叉树规则:左-右-根 1.后序遍历左子树 2.后序遍历右子树 3.访问根结点 1.  一棵二叉树的先序遍历结果为ABCDEF,中序遍历结果为CBAEDF,则后序遍历结果为(A)A. CBEFDA                       B. FEDCBAC. CBEDFA        

《数据结构与算法分析-第2章-算法分析》

2.1 数学基础 1. 掌握O(N)的概念 2. 在需要大O表示的任何分析中,各种简化都是可能发生的,低阶项一般都会被自动忽略,常数也可以弃掉 2.2 模型 1. 对模拟机做的假设: 1. 模拟机做任何一件简单的工作(加法,减法,赋值,比较)都恰好花费一个时间单元 2. 模拟机有无限的内存,不会发生缺页中断 2.3 要分析的问题 若无相关的指定,则所需要的量是最坏情况下的运行时间 例子:最大子序列和问题的三种解法时间复杂度的分析 一般来说,数据的读入是一个瓶颈,只要可能,使得算法足够有效且不会导

java数据结构和算法-----第四章

栈和队列 栈(后进先出) 栈,只允许访问一个数据项:即最后插入的数据项. 栈可以用来检查括号的匹配问题和解析数学表达式,类似于在编译原理中的使用. 该图片的操作实际上归纳起来:1.读到左分隔符入栈,2.读到右分隔符就和从栈顶弹出来的左分割符匹配,匹配成功,就正常进行. 3.读到一般的字母字符,就过滤掉.栈的入栈和出栈的时间复杂度都是O(1) 队列(先进先出) 队列的主要有以下几种方法:insert(),remove(),peek(),isFull(),isEmpty()和size()

数据结构与算法分析——第七章 排序

7.1 预备知识 1,算法接收 含元素的数组和包含元素个数的整数 2,基于比较的排序 7.2 插入排序 代码实现 void InsertionSort(ElementType A[],int N) { int i,j; ElementType Tmp; for(i = 1 ; i < N ; i++) { Tmp = A[i]; for(j = i ; j > 0 && A[j - 1] > Tmp ; j--) { A[j] = A[j - 1]; } A[j] = T