数据结构----树

一、树(Tree

1.树:是n(n>=0)个结点的有限集。

n=0时称为空树。

在任意一颗非空树中:

(1)有且仅有一个特定的称为根(ROOT)的结点;

(2)n>1时,其余结点可分为m(m>0)个互不相交的有限集T1T2...Tm,其中每一个集合本身又是一棵树,并且称为根的子树(SubTree).

2. 结点分类

(Degree):结点拥有的子树数

叶结点(Leaf/(非终端结点):度为0的结点

分支结点(终端节点):度不为0的结点,除根结点之外,分支结点也称为内部结点

树的度:树内各节点的度的最大值

孩子结点:结点的直接后继

双亲结点:孩子结点的直接前驱

子孙结点:孩子结点的孩子结点

祖先节点:双亲结点的双亲结点

兄弟结点:同一个结点的孩子结点互称兄弟结点

堂兄弟结点:双亲在同一层的结点互为堂兄弟

3. 层次

树中结点的最大层次称为树的深度(Depth)或高度。

有序树: 如果将树中结点的各子树看成从左至右是有次序的,不能互换,称为有序树,否则称为无序树。

森林(Forest)m(m>=0)棵互不相交的树的集合。对树中的每个结点而言,其子树的集合即为森林。

4.线性表和树结构的区别:

在一定情况下,线性表可以看成特殊的树结构


5.树的操作

创建树、销毁树、清空树、插入结点、删除结点、获取结点、获取根结点、获取树的结点数、获取树的高度、获取树的度

6.树的存储结构表示方法:

双亲表示法,孩子表示法,孩子兄弟表示法;

a)双亲表示法

#define  MAX_TREE_SIZE  100

typedef struct PTNode
{
    int data;                     //结点数据
    int parent;                  // 双亲位置
}PTNode;

typedef struct{                   //树结构
    PTNode nodes[MAX_TREE_SIZE];  
    int r,n;                      //根的位置和结点数
}PTree;

b)孩子表示法

每个结点有多个指针域,其中每个指针指向一个子树的根结点的方法叫做多重链表表示法。

/*树的孩子表示法结点结构定义  */
#define MAXSIZE 100
typedef int ElemType;		//树结点的数据类型,暂定为整形 
typedef struct CTNode		//孩子结点
{
	int child;
	struct CTNode *next;
}*ChildPtr;

typedef struct				//表头结构
{
	int  data;
	ChildPtr firstchild;
}CTBox;

typedef struct				//树结构
{
	CTBox nodes[MAXSIZE];	             //结点数组
	int r,n;				//根结点的位置和结点数
}CTree;

c)孩子兄弟表示法:

    任意一棵树,它的结点的第一个孩子如果存在就是唯一的,它的右兄弟如果存在也是唯一的。

/*树的孩子兄弟表示法结构定义 */
typedef struct CSNode
{
	int  data;
	struct CSNode  *firstchild, *rightsib;
}CSNode, *CSTree;

二、二叉树

1.二叉树:是n(n>=0)个结点的有限集合,该集合或者为空集(称为空二叉树),或者由一个根结点和两棵互不相交的,

      分别称为根结点的左子树和右子树的二叉树组成。

 

 特点:

 ①每个结点最多有两棵子树,所以二叉树中不存在度大于2的结点。

 ②左子树和右子树是有顺序的,次序不能任意颠倒。

③即使树中结点只有一颗子树,也要区分它是左子树和右子树。

2.二叉树具有五种基本形态:

 ①空二叉树;

 ②只有一个根结点

 ③根结点只有左子树

 ④根结点只有右结点

 ⑤根结点既有左子树又有右子树

3.特殊二叉树

a)斜树:所有的结点都只有左子树的二叉树叫做左斜树;只有右子树的二叉树叫右斜树;统统称为斜树;

b)满二叉树:在一颗二叉树中,如果所有分支结点都存在左子树和右子树,并且所有叶子都在同一层上,这样的二叉树称为满二叉树;

 特点:

 1) 叶子只能出现在最小一层。

 2) 非叶子结点的度一定是2

 3) 在同样深度的二叉树中,满二叉树的结点个数最多,叶子数最多。

c)完全二叉树

    对一棵具有n个结点的二叉树按层次编号,如果编号为i的结点与同样深度的满二叉树中编号 为i的结点在二叉树中位置完全相同,则这棵二叉树称为完全二叉树。

 

 特点:

 1)叶子结点只能出现在最小两层;

 2)最下层的叶子一定集中在左部连续位置;

 3)倒数二层,若有叶子结点,一定都在右部连续位置;

 4) 如果结点度为1, 则该结点只有左孩子,即不存在只有右子树的情况;

 5)同样结点树的二叉树,完全二叉树的深度最小。

4.二叉树的存储结构:

①二叉树的顺序存储:用一组连续的存储单元存放二叉树中的结点。 必须把二叉树的所有点安排成为一个恰当的序列,缺点是有可能对存储空间造成极大的浪费。依据二叉树的性质,完全二叉树采用顺序存储比较合适。

#define Maxsize 100     //假设一维数组最多存放100个元素
typedef char Datatype;  //假设二叉树元素的数据类型为字符

typedef struct
{ 
    Datatype bt[Maxsize];
    int btnum;
}Btseq;

②二叉链表二叉树每个结点最多的有两个孩子,所以它设计一个数据域和两个指针域,这样的链表叫做二叉链表:

data域存放某结点的数据信息;

lchildrchild分别存放指向左孩子和右孩子的指针,当左孩子或右孩子不存在时,相应指针域值为空(用符号∧或NULL表示)。利用这样的结点结构表示的二叉树的链式存储结构被称为二叉链表。

typedef struct BiTNode{    
        int data;              
        struct BiTNode *lchild, *rchild;    
}BiTNode,*BiTree;

5.遍历二叉树

①前序遍历:规则是若二叉树为空,则空操作返回,否则先访问根结点,然后前序遍历左子树,再前向遍历右子树。

前序遍历算法

void  PreOrderTraverse(BiTree T)
 {
     if(T == NULL)
         return ;
     printf("%c", T->data);   
     PreOrderTraverse(T->lchild);   
     PreOrderTraverse(T->rchild);   
     
 }

②中序遍历:中序遍历左子树,访问根结点中的数据,中序遍历右子树

中序遍历算法

void InOrderTraverse(BitTree T)
{
    if(T == NULL)
        return;
    InOrderTraverse(T->lchild);  
    printf("%c",T->data);         
    InOrderTraverse(T->rchild);    
}

③后序遍历:后序遍历左子树,后序遍历右子树,访问根结点中的数据

后序遍历算法

void PostOrderTraverse(BiTree T)
{
     if(T == NULL)
         return;
     PostOrderTraverse(T->lchild);   
     PostOrderTraverse(T->rchild);   
     printf("%c",T->data);          
}

④层序遍历:按层依次遍历

 

6. 二叉树的建立

void  CreateBiTree(BiTree *T)
 {
     int ch;
     scanf("%c", &ch);
     if(ch == '#')
         *T = NULL;
     else
     {
         *T = (BiTree)malloc(sizeof(BiTNode));
         if(!*T)
             exit(OVERFLOW);
         (*T)->data = ch;              
         CreateBiTree(&(*T)->lchild);  
         CreateBiTree(&(*T)->rchild);  
     }
 }

6. 线索二叉树

线索二叉树原理:这种指向前驱和后继的指针称为线索,加上线索的二叉链表称为线索链表,

对应的二叉树就称为线索二叉树。

对二叉树以某种次序遍历使其变为线索二叉树的过程就是线索化。

线索二叉树结构实现

typedef enum{Link, Thread} PointerTag;                      // Link==0,表示指向左右孩子指针;Thread == 1 表示指向前驱或后继的线索

typedef struct BiThrNode{                                   // 二叉线索存储结点结构
     int data;                      
     struct BiThrNode *lchild,*rchild;       
     PointerTag LTag;
     PointerTag RTag;                                          //左右标志
} BiThrNode, *BiThrTree;








评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值