树(1)————简单了解二叉树

树储存结构

  • 通过前面线性表的学习,现在我们来接触一种新的数据结构。树结构是一种倒立的树,作为一种非线性存储结构,它存储的是具有“一对多”关系的数据元素的集合。

了解树的概念

树(1)————简单了解二叉树_第1张图片

  • 树是 n(n>=0)个结点的有限集,当n = 0时,就被称为空树。

  • 很明显,通过分析,我们也发现几个结论。1.树的根结点没有前驱。2.每个结点有且只有一个前驱。3.每个结点可以有零个或很多个后继。

了解树的术语

  • 树和子树:以根结点为根的树为全树,以其他结点作为根结点的树为子树

  • 结点的度:表示当前结点拥有的分支个数

  • 树的度:就是当前树结点最多拥有的度

  • 叶子结点:度为0的结点就是叶子结点,它位于树最深层

  • 树根结点:每一个非空树都有且只有一个被称为根的结点。此外如果一个结点没有父结点,那么这个结点就是整棵树的根结点

  • 父结点:若一个结点含有子结点,则这个结点称为其子结点的父结点

  • 子结点:一个结点含有的子树的根结点称为该结点的子结点

  • 祖先:对任意结点x,从根结点到结点x的所有结点都是x的祖先(结点x也是自己的祖先)

  • 子孙:对任意结点x,从结点x到叶子结点的所有结点都是x的子孙(结点x也是自己的子孙)

  • 兄弟结点:拥有共同父结点的结点互称为兄弟结点

  • 路径:从一个结点到另一个结点之间的边和结点构成路径

  • 层次:树根开始定义,根结点为第1层,它的子结点为第2层,以此类推

  • 结点的深度:对任意结点x,x结点的深度表示为根结点到x结点的路径长度。所以根结点深度为0,第二层结点深度为1

  • 树的深度:类似树的度对应于结点的度一样,最深的结点的深度

  • 结点高度:对任意结点x,叶子结点到x结点的路径长度就是结点x的高度

  • 森林:由 m (m >= 0)个互不相交的树组成的集合被称为森林。(上图以B,C为根节点的两棵子树就可以被称为森林)

什么是二叉树

  • 要了解二叉树,我们可以先简单了解一些普通树的类型。
  • 无序树:树的任意节点的子节点没有顺序关系。
  • 有序树:树的任意节点的子节点有顺序关系。
  • 二叉树:树的任意节点至多包含两棵子树
  • 满二叉树:叶子节点都在同一层并且除叶子节点外的所有节点都有两个子节点。

二叉树的存储结构

二叉树的顺序存储结构

  • 二叉树的顺序存储,指的是使用顺序表(数组)存储二叉树。
  • 但是在用顺序表来存储二叉树是有限制条件的,只有完全二叉树才能使用顺序存储结构。所以如果我们要存储普通二叉树,就要把它转化成完全二叉树。
    树(1)————简单了解二叉树_第2张图片
  • 完全二叉树的顺序存储,仅需从根节点开始,按照层次依次将树中节点存储到数组即可。
  • 例如上面的完全二叉树,存储成 1 2 0 3 0 0 0 0

二叉树的链式存储结构

  • 由于使用数组来存储二叉树具有很明显的局限性,所以我们更为常用的是使用链表来对二叉树进行存储。
  • 而用链表来存储二叉树,我们只要在结构体中设置两个指针指向左右孩子就行了。
    在这里插入图片描述
  • 而整个树可以表示成下面这种形式。

树(1)————简单了解二叉树_第3张图片

typedef struct BiTNode{
    TElemType data;//存放数据
    struct BiTNode *lchild,*rchild;//左右孩子指针
}BiTNode,*BiTree;

如何遍历二叉树

  • 简单的介绍完两种存储结构,现在我们来介绍二叉树的遍历方法

✨先序遍历

访问根节点;
访问当前节点的左子树;
若当前节点无左子树,则访问当前节点的右子树;

树(1)————简单了解二叉树_第4张图片

  • 让我们用递归写一下先序遍历
#include 
#include 
#define TElemType int
typedef struct BiTNode{
    TElemType data;//数据域
    struct BiTNode *lchild,*rchild;//左右孩子指针
}BiTNode,*BiTree;

void visit(BiTNode* elem){
    printf("%d ",elem->data);
}
void PreOrder(BiTree T){
	if(T != NULL){
		visit(T);	//访问根节点
		PreOrder(T->lchild);	//递归遍历左子树
		PreOrder(T->rchild);	//递归遍历右子树
	}
	return ;
}//仅展示部分代码

✨中序遍历

访问当前节点的左子树;
访问根节点;
访问当前节点的右子树;

#include 
#include 
#define TElemType int
typedef struct BiTNode{
    TElemType data;//数据域
    struct BiTNode *lchild,*rchild;//左右孩子指针
}BiTNode,*BiTree;

void visit(BiTNode* elem){
    printf("%d ",elem->data);//把遍历完成的数输出来
}
void PreOrder(BiTree T){
	if(T != NULL){
	    PreOrder(T->lchild);	//递归遍历左子树
		visit(T);	//访问根节点
		PreOrder(T->rchild);	//递归遍历右子树
	}
	return ;
}//仅展示部分代码

树(1)————简单了解二叉树_第5张图片

✨后序遍历

从根节点出发,依次遍历各节点的左右子树。
直到当前节点左右子树遍历完成后,才访问该节点元素。

#include 
#include 
#define TElemType int
typedef struct BiTNode{
    TElemType data;//数据域
    struct BiTNode *lchild,*rchild;//左右孩子指针
}BiTNode,*BiTree;

void visit(BiTNode* elem){
    printf("%d ",elem->data);//把遍历完成的数输出来
}
void PreOrder(BiTree T){
	if(T != NULL){
	    PreOrder(T->lchild);	//递归遍历左子树
		PreOrder(T->rchild);	//递归遍历右子树
	    visit(T);	//访问根节点
	}
	return ;

树(1)————简单了解二叉树_第6张图片

  • 我们简单的了解了下二叉树的概念,但如果要灵活运用到掌握,依然需要大量的算法积累。

你可能感兴趣的:(数据结构和算法,c语言,算法,数据结构)