数据结构 - 树

3.1 树与树的表示

引子:二分查找算法具有对数的时间复杂度O(logN)

定义:树(Tree): n(n≥0)个结点构成的有限集合。

当n=0时,称为空树;

对于任一棵非空树(n> 0),它具备以下性质:
 1. 树中有一个称为“根(Root)”的特殊结点,用 r 表示;
 2. 其余结点可分为m(m>0)个互不相交的有限集T1,T2,...,Tm,其中每个集合本身又是一棵树,称为原来树的“子树(SubTree)”

基本术语:
 1. 结点的度(Degree):结点的子树个数
 2. 树的度:树的所有结点中最大的度数
 3. 叶结点(Leaf):度为0的结点
 4. 父结点(Parent):有子树的结点是其子树的根结点的父结点
 5. 子结点(Child):若A结点是B结点的父结点,则称B结点是A结点的子结点;子结点也称孩子结点。
 6. 兄弟结点(Sibling):具有同一父结点的各结点彼此是兄弟结点。
 7. 路径和路径长度:从结点n1到nk的路径为一个结点序列n1, n2, … , nk, ni是ni+1的父结点。
 8. 路径所包含边的个数为路径的长度。 
 9. 祖先结点(Ancestor):沿树根到某一结点路径上的所有结点都是这个结点的祖先结点。
 10. 子孙结点(Descendant):某一结点的子树中的所有结点是这个结点的子孙。
 11. 结点的层次(Level):规定根结点在1层,其它任一结点的层数是其父结点的层数加1。
 12. 树的深度(Depth):树中所有结点中的最大层次是这棵树的深度。

任意树结点可以用儿子-兄弟表示法:     


3.2 二叉树及储存结构

定义:最多只有两个子结点的树结构。

特殊二叉树:
 1. 斜二叉树
 2. 完美二叉树或满二叉树

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


重要性质:
 1. 一个二叉树第 i 层的最大结点数为: 2^(i-1),i >= 1。
 2. 深度为k的二叉树有最大结点总数为: (2^k)-1,k >= 1。

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


重要操作:
 1、Boolean IsEmpty( BinTree BT ): 判别BT是否为空;
 2、void Traversal( BinTree BT ):遍历,按某顺序访问每个结点;

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


常用的 遍历方法有:
 1. void PreOrderTraversal( BinTree BT ):先序----根、左子树、右子树;
 2. void InOrderTraversal( BinTree BT ): 中序---左子树、根、右子树;
 3. void PostOrderTraversal( BinTree BT ):后序---左子树、右子树、根

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


二叉树储存结构:              


3.3 二叉树的遍历

递归实现

先序遍历:

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

中序遍历:

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

后序遍历:

void PostOrderTraversal( BinTree BT )
{
    if( BT ) {
        PostOrderTraversal( BT->Left );
        PostOrderTraversal( BT->Right);
        printf(“%d”, BT->Data);
    }
}

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


中序遍历非递归遍历算法
 1. 遇到一个结点,就把它压栈,并去遍历它的左子树;
 2. 当左子树遍历结束后,从栈顶弹出这个结点并访问它;

 3. 然后按其右指针再去中序遍历该结点的右子树。

void InOrderTraversal( BinTree BT )
{   BinTree T=BT;
    Stack S = CreatStack( MaxSize ); /*创建并初始化堆栈S*/
    while( T || !IsEmpty(S) ){
        while(T){ /*一直向左并将沿途结点压入堆栈*/
            Push(S,T);
            T = T->Left;
        }
        if(!IsEmpty(S)){
            T = Pop(S); /*结点弹出堆栈*/
            printf(“%5d”, T->Data); /*(访问)打印结点*/
            T = T->Right; /*转向右子树*/
        }
    }
}

层序遍历:

队列实现:遍历从根结点开始,首先将根结点入队,然后开始执行循环:结点出队、访问该结点、若该元素所指结点的左、右孩子结点非空,其左右儿子入队。

void LevelOrderTraversal ( BinTree BT )
{   Queue Q; BinTree T;
    if ( !BT ) return; /* 若是空树则直接返回 */
    Q = CreatQueue( MaxSize ); /*创建并初始化队列Q*/
    AddQ( Q, BT );
    while ( !IsEmptyQ( Q ) ) {
        T = DeleteQ( Q );
        printf(“%d\n”, T->Data); /*访问取出队列的结点*/
        if ( T->Left ) AddQ( Q, T->Left );
        if ( T->Right ) AddQ( Q, T->Right );
    }
}

  [1]: http://static.zybuluo.com/zhuguodong/vnjz7v01j9vh9cbk0rr3ieik/image_1c9jkeomu1k371v0dmqp1msltsk9.png
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值