树:n(>=0)个结点构成的有限集合。

当n=0时,称为空树;

对于任一课非空树(>0),它具备以下性质:

*树中有一个称为”根“的特殊结点,用r表示;

*其余结点可分别为m(>0)个互不相交的有限集T1,T2,...,Tm,其中每个集合本身又是一棵树,称原来树的”子树“

树与非树

*子树是不相交的;

*除了根结点外,每个结点有且仅有一个父结点;

*一棵N个结点的树N-1条边。

树的一些基本术语

1,结点的度:结点的子树个数

2,树的度:树的所有结点中最大的度数

3,叶结点:度为0的结点

4,父节点:有子树的结点是其子树的根结点的父结点

5,子结点

6,兄弟结点

7,路径和路径的长度

8,祖先节点

9,子孙节点

10,结点的层次

11,树的深度

树的表示

*二叉树:一个有穷的结点的集合

这个集合可以为空

若不为空,则它是由一个根节点和左子树和右子树两个不相交的二叉树组成,二叉树有五种形态,二叉树的子树有左右之分

特殊二叉树

斜二叉树,完美/满二叉树,完全二叉树

二叉树的几个重要性质

*一个二叉树第i层的最大节点数为:2^i-,i>=1.

*深度为k的二叉树有最大结点总数为:2^k-1,k>=1.

*对任何非空二叉树T,若n0表示叶节点的个数,n2是度为2的非叶节点个数,那么两者满足关系n0=n2+1

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

类型名称:二叉树

数据对象集:一个有穷的结点的集合

若不为空,则由根节点和其左、右二叉子树组成

操作集:BT(-BinTree,Item(-ElementType,重要操作有:

1,Boolean IsEmpty(BinTree BT):判别BT是否为空;

2,void Traversal(BinTree BT):遍历,按某顺序访问每个结点;

3,BinTree CreatBinTree():创建一个二叉树

常用的遍历方法有:

void preOrderTraversal(BinTree BT):先存---根、左子树、右子树;

void InOrderTraversal(BinTree BT):中序---左子树、根、右子树;

void PostOrderTraversal(BinTree BT):后序---左子树、右子树、根;

void LevelOrderTraversal(BinTree BT):层次遍历,从上到下,从左到右;

二叉树的存储结构

1,顺序存储结构

完全二叉树:按从上到下、从左到右顺序存储n个结点的完全二叉树的结点父子关系

非根节点(序号i>1)的父结点的序号是【i/2】;

结点(序号为1)的左孩子结点的序号是2i,(2i<=n,否则没有左孩子);结点i的右孩子结点的序号是2i+1,(2i+1<=n)

2,链表存储

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

二叉树的遍历

(1)先序遍历

遍历过程为:

*访问根节点;

*先序遍历其左子树;

*先序遍历其右子树;

void PreOrderTraversal(BinTree BT)
{
    if(BT) {
          printf("%d",BT->Data);
          PreOrderTraversal(BT->Left);
          PreOrderTraversal(BT->Right);
} }

(2)中序遍历

*先左子树

*根节点

*右子树

void InOrderTraversal(BinTree BT)
{
    if(BT) {
          
          InOrderTraversal(BT->Left);
          printf("%d",BT->Data);
          InOrderTraversal(BT->Right);
        }
}

(3)后序遍历

*左子树

*右子树

*根节点

二叉树的非递归遍历

*中序遍历非递归遍历算法

基本思路,使用堆栈