数据结构第三周笔记——树(上)(慕课浙大版本--XiaoYu)(二)

简介: 数据结构第三周笔记——树(上)(慕课浙大版本--XiaoYu)(二)

二叉树及存储结构


3.2.1 二叉树的定义及性质


二叉树的定义


  二叉树T:一个有穷的结点集合
​   这个集合可以为空
    若不为空,则它是由根结点和称为其左子树TL和右子树TR的两个不相交的二叉树组成(L和R是下标)


二叉树具体五种基本形态


网络异常,图片无法展示
|


二叉树的子树有左右之分


网络异常,图片无法展示
|


特殊的二叉树


斜二叉树(Skewed Binary Tree)


  1. 只有左边或者只有右边,相当于一个链表
  2. 网络异常,图片无法展示
    |


完美二叉树(Perfect Binary Tree)


或者叫做满二叉树(Full Binary Tree)


网络异常,图片无法展示
|


特点: 一个深度为k(>=-1)且有2^(k+1) - 1个结点的二叉树称为完美二叉树。 满二叉树


完全二叉树(Complete Binary Tree)


有n个结点的二叉树,对树种结点按从上到下,从左到右的顺序进行编号,编号为i(1 <= i <= n)结点与满二叉树中编号为i结点在二叉树中位置相同
跟上方的区别就是除了最底下一层可以右边缺一点,上面跟满二叉树是一样的。最底下一层左边顺序不能乱


二叉树的几个重要性质


网络异常,图片无法展示
|


叶结点的总数等于有两个儿子的结点的总数加1

有一颗二叉树,其两个儿子的结点个数为15个,一个儿子的结点个数为32个,问该二叉树的叶结点个数是多少?
16


二叉树的抽象数据类型定义


类型名称:二叉树
数据对象集:一个有穷的结点集合。
  若不为空,则由根结点和其左、右二叉子树组成。
操作集: BT属于BinTree,Item属于ElementType
重要操作有:
1.Boolean IsEmpty(BinTree BT):判别BT是否为空;
2.void Traversal(BinTree BT):遍历,按某顺序访问每个结点;(重要)
3.BinTree CreateBinTree():创建一个二叉树
常用的遍历方法
1.void PreOrderTraversal(BinTree BT)://先序--根、左子树、右子树
2.void InOrderTraversal(BinTree BT)://中序--左子树、根、右子树
3.void PostOrderTraversal(BinTree BT)://后序--左子树、右子树、根
4.void LevelOrderTraversal(BinTree BT)://层次遍历(层序遍历,从上到下、从左到右

3.2.2 二叉树的存储结构


1.顺序存储结构


完全二叉树:按从上至下,从左到右顺序存储n个结点的完全二叉树的结点父子关系;
//这个树最适合数组方式解决

网络异常,图片无法展示
|


  1. 非根结点(序号 i > 1)的父节点的序号是[i/2]
  1. 这句话的意思就是说假设我们目前知道M结点时6,如果想知道它的父节点就是6/2=3,Q结点就是7/2=3.5,把小数去掉,父节点一样是3
  1. 结点(序号为i)的左孩子结点的序号是2i,(若2i <= n,否则没有左孩子)
  1. 举例:意思就是B左孩子是C,O的左孩子是M
  1. 结点(序号为i)的右孩子结点的序号是2i+1,(若2i+1 <= n,否则没有右孩子)
  1. 举例:类似上方的意思B右孩子是S...


一般二叉树也可以采用这种结构,缺点:但会造成空间浪费....(将缺少的结点补上一个空结点)


网络异常,图片无法展示
|


网络异常,图片无法展示
|

问题:
如果参照完全二叉树的表示方法用数组存储下面这棵二叉树,那么结点e所对应的数组下标是多少(树根下标为1)?
答案:6

网络异常,图片无法展示
|


2.链表存储


网络异常,图片无法展示
|


typedef struct TreeNode *BinTree;
typedef BinTree Position;
struct TreeNode{
    ElementType Data;
    BinTree Left;
    BinTree Right;
}


网络异常,图片无法展示
|


二叉树的遍历


3.3.1 先序中序后序遍历


二叉树的遍历


(1)先序遍历
遍历过程为:
1.访问根节点
2.先序遍历其左子树
3.先序遍历其右子树 
对应的递归程序:
void PreOrderTraversal(BinTree BT)//BT是树
{
    if( BT ){//看树是不是空的,空的就退出去,不空就访问根节点
        printf("d",BT->Data);
        PreOrderTraversal(BT->Left);//指向左子树的那个根节点的地址进行递归
        PreOrderTraversal(BT->Right);//指向右子树的那个根节点的地址进行递归
    }
}


网络异常,图片无法展示
|


先是从根开始  A(B D F E)(C G H I)
先序遍历=>A B D F E C G H I
(2)中序遍历


遍历过程为:
1.中序遍历其左子树
2.访问根结点;
3.中序遍历其右子树 
对应的递归程序:
void PreOrderTraversal(BinTree BT)//BT是树
{
    if( BT ){//看树是不是空的,空的就退出去,不空就访问根节点
        PreOrderTraversal(BT->Left);//指向左子树的那个根节点的地址进行递归
        printf("d",BT->Data);
        PreOrderTraversal(BT->Right);//指向右子树的那个根节点的地址进行递归
    }
}

网络异常,图片无法展示
|


中序遍历 => D B E F A G H C I
(D B E F) A ( G H C I)
先是左边再右边,这里我原本的疑问是为什么是先E在F而不是先F再E
原因是E-F是一个树,然后因为这个是左子树,所以从左边开始,E在F的左边


网络异常,图片无法展示
|


(3)后序遍历
遍历过程为:
1.后序遍历其左子树
2.中序遍历其右子树 
3.访问根结点
对应的递归程序:
void PreOrderTraversal(BinTree BT)//BT是树
{
    if( BT ){//看树是不是空的,空的就退出去,不空就访问根节点
        PreOrderTraversal(BT->Left);//指向左子树的那个根节点的地址进行递归
        PreOrderTraversal(BT->Right);//指向右子树的那个根节点的地址进行递归
        printf("d",BT->Data);
    }
}

网络异常,图片无法展示
|


注意点:后序遍历,那当然得从下面开始咯,所以会发现B跟E是E优先。H跟C比是H优先
 (D E F B)(H G I C) A
 后序遍历 => D E F B H G I C A


总结


先序、中序和后序遍历过程:遍历过程中经过结点的路线一样,只是访问各结点的时机不同
图中先从入口到出口的曲线上用三种符号分别标记除先序,中序和后序的访问各结点时刻


网络异常,图片无法展示
|


3.3.2 中序非递归遍历


二叉树的非递归遍历


中序遍历非递归遍历算法


非递归算法实现的基本思路:使用堆栈


这里建议看视频的演示,非常形象


1.遇到一个结点,就把它压栈,并去遍历它的左子树;
2.当左子树遍历结束后,从栈顶弹出这个结点并访问它;
3.然后按其右指针再去中序遍历该结点的右子树
以下是完整代码实现演示
void InOrderTraversal(BinTree BT)
{
    BinTree T = BT;//把BT赋给临时变量T
    Stack S = CreateStack(MaxSize);//创建并初始化堆栈
    while(T || !IsEmpty(S) ){//树不空且堆栈不空
        while(T){//判断堆栈空不空
            //一直向左并将沿途结点压入堆栈
            Push(S,T);//把T压入堆栈S中
            T = T->Left;//然后把T往左挪,就是边挪边把结点压到堆栈里面去,压到底T为NULL就退出来
        }
        if(!IsEmpty(S)){
            T = Pop(S);//结点弹出堆栈
            printf("%5d",T->Data);//(访问)打印结点
            T = T->Right;//转向右子树
        }
    }
}
ppoopoppoo错误
PPOPOOPPOO正确
    第二次碰到同一个的时候就print出来


网络异常,图片无法展示
|


先序遍历的非递归遍历算法?


把上方那个算法中if中的printf("%5d",T->Data)移到while(T)中Push的后面


后序遍历非递归遍历算法?
目录
相关文章
|
1月前
|
算法
数据结构之博弈树搜索(深度优先搜索)
本文介绍了使用深度优先搜索(DFS)算法在二叉树中执行遍历及构建链表的过程。首先定义了二叉树节点`TreeNode`和链表节点`ListNode`的结构体。通过递归函数`dfs`实现了二叉树的深度优先遍历,按预序(根、左、右)输出节点值。接着,通过`buildLinkedList`函数根据DFS遍历的顺序构建了一个单链表,展示了如何将树结构转换为线性结构。最后,讨论了此算法的优点,如实现简单和内存效率高,同时也指出了潜在的内存管理问题,并分析了算法的时间复杂度。
54 0
|
1月前
|
存储 缓存 算法
在C语言中,数据结构是构建高效程序的基石。本文探讨了数组、链表、栈、队列、树和图等常见数据结构的特点、应用及实现方式
在C语言中,数据结构是构建高效程序的基石。本文探讨了数组、链表、栈、队列、树和图等常见数据结构的特点、应用及实现方式,强调了合理选择数据结构的重要性,并通过案例分析展示了其在实际项目中的应用,旨在帮助读者提升编程能力。
55 5
|
1月前
|
存储 搜索推荐 算法
【数据结构】树型结构详解 + 堆的实现(c语言)(附源码)
本文介绍了树和二叉树的基本概念及结构,重点讲解了堆这一重要的数据结构。堆是一种特殊的完全二叉树,常用于实现优先队列和高效的排序算法(如堆排序)。文章详细描述了堆的性质、存储方式及其实现方法,包括插入、删除和取堆顶数据等操作的具体实现。通过这些内容,读者可以全面了解堆的原理和应用。
94 16
|
1月前
|
算法
数据结构之文件系统模拟(树数据结构)
本文介绍了文件系统模拟及其核心概念,包括树状数据结构、节点结构、文件系统类和相关操作。通过构建虚拟环境,模拟文件的创建、删除、移动、搜索等操作,展示了文件系统的基本功能和性能。代码示例演示了这些操作的具体实现,包括文件和目录的创建、移动和删除。文章还讨论了该算法的优势和局限性,如灵活性高但节点移除效率低等问题。
57 0
|
2月前
|
存储 算法 关系型数据库
数据结构与算法学习二一:多路查找树、二叉树与B树、2-3树、B+树、B*树。(本章为了解基本知识即可,不做代码学习)
这篇文章主要介绍了多路查找树的基本概念,包括二叉树的局限性、多叉树的优化、B树及其变体(如2-3树、B+树、B*树)的特点和应用,旨在帮助读者理解这些数据结构在文件系统和数据库系统中的重要性和效率。
32 0
数据结构与算法学习二一:多路查找树、二叉树与B树、2-3树、B+树、B*树。(本章为了解基本知识即可,不做代码学习)
|
2月前
|
Java C++
【数据结构】探索红黑树的奥秘:自平衡原理图解及与二叉查找树的比较
本文深入解析红黑树的自平衡原理,介绍其五大原则,并通过图解和代码示例展示其内部机制。同时,对比红黑树与二叉查找树的性能差异,帮助读者更好地理解这两种数据结构的特点和应用场景。
42 0
|
1月前
|
C语言
【数据结构】栈和队列(c语言实现)(附源码)
本文介绍了栈和队列两种数据结构。栈是一种只能在一端进行插入和删除操作的线性表,遵循“先进后出”原则;队列则在一端插入、另一端删除,遵循“先进先出”原则。文章详细讲解了栈和队列的结构定义、方法声明及实现,并提供了完整的代码示例。栈和队列在实际应用中非常广泛,如二叉树的层序遍历和快速排序的非递归实现等。
218 9
|
1月前
|
存储 算法
非递归实现后序遍历时,如何避免栈溢出?
后序遍历的递归实现和非递归实现各有优缺点,在实际应用中需要根据具体的问题需求、二叉树的特点以及性能和空间的限制等因素来选择合适的实现方式。
37 1
|
1月前
|
存储 算法 Java
数据结构的栈
栈作为一种简单而高效的数据结构,在计算机科学和软件开发中有着广泛的应用。通过合理地使用栈,可以有效地解决许多与数据存储和操作相关的问题。