数据结构课总结

一些概念的解释

完全二叉树

满二叉树

树的深度
根结点的深度为1,离根结点越远的结点深度越大
树的高度
叶结点的高度为1,一个结点的高度=max(左子树高度,右子树高度)+1
森林
几棵树的集合
三叉链表
增加了指向父结点的指针
前驱结点、后继结点
用二叉搜索树来解释会比较清楚。
前驱结点就是后一个小于当前结点的结点。(中序遍历时的前一个节点)
后继结点就是后一个大于当前结点的结点。(中序遍历时的后一个节点)
线索二叉树
如果一个结点的左孩子为空,则指向它的前驱结点。
如果一个结点右孩子为空,则指向它的后继。
相应的,需要增加两个标记变量记录孩子结点是否为空。

树的重建

树的重建的意义在于从硬盘里读取信息后能够还原这棵树(硬盘存储没有指针的概念)。
中序遍历有一个很大的作用,就是确定这个结点的左右子树都有哪些,从而帮助我们进行定位。
根据先序遍历和中序遍历还原

void recoverByPreAndMid(int tree[], int pre[], int mid[], int n)
{
    for (int i = 1; i < maxn; i++) //初始化,-1表示空结点
        tree[i] = -1;
    unordered_map<int, int> index;
    for (int i = 1; i <= n; i++)
        index[mid[i]] = i; //记录结点在中序遍历中的下标
    for (int i = 1; i <= n; i++)
    {
        int cur = 1;
        while (tree[cur] != -1)
        {
            if (index[pre[i]] < index[tree[cur]]) //位于左子树
                cur = cur * 2;
            else //位于右子树
                cur = cur * 2 + 1;
        }
        tree[cur] = pre[i];
    }
}

根据中序遍历和后序遍历还原

void recoverByMidAndLast(int tree[], int mid[], int last[], int n)
{
    for (int i = 1; i < maxn; i++) //初始化,-1表示空结点
        tree[i] = -1;
    unordered_map<int, int> index;
    for (int i = 1; i <= n; i++)
        index[mid[i]] = i; //记录结点在中序遍历中的下标
    for (int i = n; i >= 1; i--)
    {
        int cur = 1;
        while (tree[cur] != -1)
        {
            if (index[last[i]] < index[tree[cur]]) //位于左子树
                cur = cur * 2;
            else //位于右子树
                cur = cur * 2 + 1;
        }
        tree[cur] = last[i];
    }
}

根据层序遍历和中序遍历还原

void recoverByMidAndSqu(int tree[], int mid[], int squ[], int n)
{
    for (int i = 1; i < maxn; i++) //初始化,-1表示空结点
        tree[i] = -1;
    unordered_map<int, int> index;
    for (int i = 1; i <= n; i++)
        index[mid[i]] = i; //记录结点在中序遍历中的下标
    for (int i = 1; i <= n; i++)
    {
        int cur = 1;
        while (tree[cur] != -1)
        {
            if (index[squ[i]] < index[tree[cur]]) //位于左子树
                cur = cur * 2;
            else //位于右子树
                cur = cur * 2 + 1;
        }
        tree[cur] = squ[i];
    }
}

其实三种方法的实现只有循环时的起始下标不同,其他都是一样的。还原二叉树的思想就是在当前选定的这个点的父结点必须在之前就被选定过,这样才能准确根据中序遍历确定当前结点的位置。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值