考研408总结【数据结构】---树与二叉树(上)

944 阅读3分钟

这是我参与11月更文挑战的第2天,活动详情查看:2021最后一次更文挑战

考研倒计时:53天

参考资料: 王道数据结构考研复习指导 天勤数据结构高分笔记

本篇先总结树的基本概念和计算、二叉树的遍历和线索二叉树的内容。

下篇总结树和森林、以及应用(二叉排序树、平衡二叉树、哈夫曼树)的内容。

树的性质

  1. 树的结点数等于所有结点的度数加1.

  2. 度为m的树中第i层上至多有mi1m^{i-1}个结点(i>=1)

  3. 高度为h,度为m的树【度为m的树指的是结点最多有m个孩子结点】至多有mh1m1\frac{m^{h}-1}{m-1}个结点. (推导利用等比数列的求和公式)

  4. 具有sum个结点,度为m的树的最小高度为logm(sum(m1)+1)\lceil log_m(sum(m-1)+1) \rceil (利用第三个公式逆推得到h,注意是向上取整)

二叉树的性质

  1. 二叉树的第i层上至多有2i12^{i-1}个结点

  2. 深度为k的二叉树至多有2k12^k-1个结点.

  3. 对于一棵非空二叉树,如果叶子节点数为m0m_0,度为2的结点数m2m_2,则有m0=m2+1m_0=m_2+1 (重点经常在选择题遇到!!!)

  4. 具有n个结点的完全二叉树的深度为log2n+1\lfloor log_2 n \rfloor+1

  5. 任何一棵完全二叉树中度为1的结点数要么有1个,要么就没有.

二叉树的遍历

下面是三种遍历的递归代码,后续很多题型以此拓展得来。

//二叉树的存储结构
typedef struct BTNode{
    char data;
    struct BTNode *lchild;
    struct BTNode *rchild;
}

//先序遍历 根左右
void preorder(BTNode *p){
    if(p!=NULL){
        Visit(p);//对p进行访问。比如打印p对应的数值
        
        preorder(p->lchild);
        preorder(p->rchild);
    }
}

//中序遍历 左根右
void inorder(BTNode *p){
    if(p!=NULL){
        inorder(p->lchild);
        Visit(p);
        inorder(p->rchild);
    }
}

//后序遍历 左右根
void postorder(BTNode *p){
    if(p!=NULL){
        postorder(p->lchild);
        postorder(p->rchild);
        Visit(p);
    }
}

相关题型

  1. 表达式(a-(b+c))*(d/e)存储在一棵以二叉链表为存储结构的二叉树中,编写程序求表达式的值。(提示,左右子树不为空则为表达式,用后序遍历求值,左右子树都为空,则为数值)
  2. 求一棵二叉树的深度。(提示左右子树深度最大值+1)
  3. 查找二叉树中等于key的结点是否存在。
  4. 根据前和后遍历序列不能确定二叉树
  5. 输出先序(中/后)遍历序列中第k个结点的值
  6. 使用非递归算法描述先序后序中序代码(利用栈)

下面是层次遍历的代码

//层次遍历
void level(BTNode *p){
    int front,rear;
    BTNode *que[maxSize];  //定义一个循环队列
    front=rear=0;
    BTNode *q;
    if(p!=NULL){
        rear=(rear+1)%maxSize;
        que[rear]=p;                    //根结点入队
        while(front!=rear){
            front=(front+1)%maxSize;
            q=que[front];               //队头结点出队
            Visit(q);
            if(q->lchild!=NULL){        //左子树不空,左子树的根结点入队
                rear=(rear+1)%maxSize;
                que[rear]=q->lchild;
            }
            if(q->rchild!=NULL){        //右子树不空,右子树的根结点入队
                rear=(rear+1)%maxSize;
                que[rear]=q->rchild;
            }
        }
    }
}

线索二叉树

有一棵结点数目为n的二叉树,采用二叉链表的形式存储。二叉链表中存在n+1个空指针域。

可以利用这些空指针进行线索化。

若结点的左子树为空,则该结点的左孩子指针指向其前驱结点。

若结点的右子树为空,则该结点的右孩子指针指向其后继结点。

图片来自Chilan Yuk

image.png

【习题】

【2010年408】 image.png

点击查看答案D 做对了嘛xdm!

【2014年408】

image.png

点击查看答案 还是选D!

部分内容待补充完善~

如有误,请多指正!