数据结构之树与二叉树

北航软件工程专业考研991数据结构总结:

五、树与二叉树
1.树与二叉树的基本概念,基本特征、名词术语;
2.完全二叉树与满二叉树的基本概念,二叉树的基本性质及其应用;
3.二叉树的顺序存储结构与二叉链表存储结的基本原理;
4.二叉树的前序遍历、中序遍历、后序遍历和按层次遍历,重点是二叉树在以二叉链表作为存储结构基础上各种遍历算法(包括非递归算法)的设计与应用;
5.二叉排序树的基本概念、建立(插入)、查找以及平均查找长度ASL的计算。

1、树与二叉树的基本概念,基本特征,名词术语

基本概念:

    树的定义:结点的集合 + 节点之间关系的集合
    n >= 0个数据组成的结构及其之间的关系。n = 0 成为空树,只有一个根节点,除了根节点每个节点只有一个直接前驱,但是有多个直接后继。

    任何一棵非空树中,有一个特殊节点t属于结点集合D,称为根节点,其余节点被分为m个子集 D1, D2, D3 ... 每个子集又是一棵树,称为t的子树。

基本特征:

    1)、有且仅有一个节点没有前驱结点,为该树的根节点;
    2)、除了根节点之外,每个节点有且仅有一个前驱结点;
    3)、包括根结点在内,每个节点可以有多个后继节点;

    一对多的关系。
    
名词术语:

    1)、结点的度:该节点拥有的子树;
    2)、树的度:树中所有结点的度的最大值;
    3)、叶结点:度为0的结点;
    4)、分支结点:度不为0的结点;
    5)、层:根结点在第一层,其余结点若在第i层,则其孩子结点在第i+1层;
    6)、树的深度:结点所处的最大层数;
    7)、树林(森林):m >= 0 棵不相交的子树组成的树的集合;
    8)、树的有序性:若结点的相对位置不能随意改变,有序树,否则,无序树;
    
二叉树: 

定义:结点 + 结点的关系构成的集合。

    要么是一棵空树,要么是一棵包含根结点,以及两颗不相交的,分别称为左子树,右子树的二叉树。
    
    
基本特征:

    要么是空树,要么只有根结点,要么有一个左子树,右子树空,要么一棵右子树,左子树空,要么两个非空左右子树。


2、完全二叉树与满二叉树的基本概念,二叉树的基本性质及应用

满二叉树:要么没有,要么有两个孩子节点,且度为0的节点都在最后一层。FULL 
完全二叉树:为了顺序存储的方便,最下面两层可以度为0,并且最后一层必须从左至右排列。
            如果排除最后一层,就是一棵满二叉树。

性质:
    1)、n个结点的非空二叉树有n-1个分支;每个结点除了根结点外,都只有一条到直接前驱的分支,故分支总数就是n-1;
    2)、非空二叉树i层最多有2^(i-1)个结点;
    3)、深度为h的非空二叉树最多有 2^h -1 个结点;
    4)、n0 = n2 + 1;  n = n1 + n2 + n0; B = n-1; B = n1 + 2n2; 
    5)、具有n个结点的非空完全二叉树的深度h = [log2 n] + 1;  []取整
    6)、完全二叉树的编号问题,从上到下,从左到有进行编号,则:
        ①、若i = 1,则i号结点为根结点;
            若i > 1,则i号结点的双亲结点的编号为[i/2];
        ②、若2i > n,则编号为i的结点没有左子树;
            若2i <= n,则编号为i的结点的左孩子编号为2i;
        ③、若2i+1 > n,则编号为i的结点没有右子树;
            若2i+1 <= n,则编号为i的结点右孩子编号为2i+1;
    

3、二叉树的顺序存储结构与二叉链表存储结构的基本原理

顺序存储结构
    1)、完全二叉树的顺序存储结构
        按照编号依次存储到一维数组[0..2^n-2]中,编号与数组下标一一对应
    2)、一般二叉树的顺序存储结构
        构造不存在的虚结点,使其成为一棵完全二叉树,在用一维数组[0..2^n-2]存储即可
        
二叉树的链式存储(二叉链表)
    链节点  lchild data rchild  data为数据域,lchild为左子树指针,rchild为右子树指针
    
    typedef struct node{
        int data;
        struct node *lchild, *rchild;
    }BTNode, *BTree;
    
4、二叉树的前序遍历,中序遍历,后序遍历,按层遍历,重点是二叉树按二叉链表为存储结构的各种遍历算法(包括非递归算法)的设计与应用

概念:按照一定的原则(顺序)对二叉树中的结点进行访问(且仅访问一次),得到一个二叉树所有结点做成的序列,这个过程叫做二叉树的遍历

前序遍历:
    原则:若二叉树非空,访问根节点;
          以前序遍历原则遍历根结点的左子树;
          以前序遍历原则遍历根结点的右子树;
          
    递归算法:
    
    void PreOrder(BTree t)
    {
        if(t != NULL)
        {
            visit(t);
            PreOrder(t->lchild);
            preOrder(t->rchild);
        }
    }
    
中序遍历:
    原则:若被遍历的二叉树非空;
          以中序遍历原则遍历根结点的左子树;
          访问根结点;
          以中序遍历原则遍历根结点的右子树;
          
    递归算法:
    
    void InOrder(BTree t)
    {
        if(t != NULL)
        {
            InOrder(t->lchild);
            visit(t);
            InOrder(t->rchild);
        }
    }
    
后序遍历:
    原则:若被遍历的二叉树非空;
          以后序遍历原则遍历根结点的左子树;
          以后序遍历原则遍历根结点的右子树;
          访问根结点;
          
    递归算法:
    
    void PostOrder(BTree t)
    {
        if(t != NULL)
        {
            PostOrder(t->lchild);
            PostOrder(t->rchild);
            visit(t);
        }
    }
    
按层次遍历:
    
非递归算法的设计:
以中序遍历为例:

STACK[0..M-1] 保存遍历过程中结点的地址;
top指针,栈顶指针,初始-1;
p 遍历过程中指向结点的指针,初始指向根结点

描述:
1)、若p指向结点非空,则将p进栈,然后p指向左子树根结点;
2)、若p指向为空,则将栈顶元素退栈赋值给p,访问该结点,然后将p指向右子树的根;
3)、重复上述过程,直到p为空,栈为空。

算法:

void InOrder(BTree t)
{
    BTree Stack[M];
    int top = -1;
    BTree p = t;
    
    do
    {
        while(p != NULL)
        {
            Stack[++top] = p;
            p = p->lchild;
        }
        p = Stack[top--];
        visit(p);
        p = p->rchild;
    }while(p != NULL || top != -1)
}

4、二叉排序树的基本概念,建立(插入),查找以及平均查找长度ASL的计算

基本概念:

定义:二叉排序树或者是空树,或者具有下列性质:
      若根结点左子树不为空,则左子树上所有结点的值都小于根结点的值;
      若根结点右子树不为空,则右子树上所有结点的值都大于或者等于根结点的值。
      

建立(插入)逐点插入:

    设K具有n个元素,没取一个元素,按照下述原则进行插入:

    若二叉树为空,则将该元素作为根结点;
    若不为空,则与根结点进行比较,若小于根结点的值,则插入左子树,若大于根结点,则插入右子树,插入子树的时候也遵循这一原则

    void InsertBST(BTree *t, int item)
    {
        BTree p, q;
        p = (BTree)malloc(sizeof(BTNode));

        p->data = item;
        p->lchild = NULL;
        p->rchild = NULL;
        
        if (*t == NULL)
            *t = p;
        else
        {
            q = *t;
            while(1)
            {
                if(item < q->data)
                {
                    if(q->lchild == NULL)
                    {
                        q->lchild = p;
                        break;
                    }else
                    {
                        q = q->lchild;
                    }
                }
                else
                {
                    if(q->rchild == NULL)
                    {
                        q->rchild = p;
                        break;
                    }
                    else
                    {
                        q = q->rchild;
                    }
                }
            }
        }
    }

查找 

过程:
    1)、若二叉树为空,则查找失败,结束;
    2)、若二叉树非空,将要查找的值与根结点的值进行比较,如果相等,则返回根结点的链地址,查找成功,结束;
    3)、若要查找的值小于根结点的值,则到根结点的左子树中继续上述查找;
    4)、若要查找的值大于根结点的值,则到根结点的右子树中继续上述查找;
    5)、知道查找成功或失败。
    
    
    BTree SortSearch(BTree t, int data)
    {
        BTree p = t;
        while (p != NULL)
        {
            if (p->data == data)
                return p;
            else if (p->data > data)
                p = p->lchild;
            else
                p = p->rchild;
        }
        return  NULL;
    }
    
平均查找长度ASL

与二叉树的形态有关;
平均查找长度ASL:确定一个元素在树中的位置所需要进行比较次数的期望值
内路径长度:从根结点到某节点所经过的分支数目叫做该结点的路径,内路径是所有结点的路径之和 IPL Internal Path Length
外路径长度:将二叉树的叶结点进行补充,用方块表示,得到的所有外部结点的路径之和为外路径长度 EPL External Path Length 
            如果二叉树有n个结点,则补充之后有n+1个外部结点
            EPL = IPL + 2n 
            
            比较次数是结点路径 + 1
            ASL = (IPL + n)/n 
            查找不成功时,比较次数就是外路径长度
            ASL = (EPL)/n = (IPL + 2n)/n 
            最后,成功与不成功的统一ASL
            (IPL + n + EPL)/(n + n + 1) = (2IPL + 3n) / (2n+1)
            
            最佳二叉排序树,内路径最小 O(log2N)
            最坏情况下,与顺序相同 (n+1)/2,相当于一棵单支二叉树

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章