IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 数据结构与算法 -> 线索二叉树根据任意结点P找前驱和后继 -> 正文阅读

[数据结构与算法]线索二叉树根据任意结点P找前驱和后继

二叉树结构

typedef struct threadNode
{
    /* data */
    ElemType data;
    threadNode *lchild, *rchild;
    /*
    
        tag = 0 指针指向孩子
        tag = 1 线索指针
    */
    int ltag, rtag;
} threadNode, *threadTree;

一,先序线索二叉树

1.前驱

先序遍历是 (根左右), 我们是通过子节点的线索来找根节点( P )的前驱和后继,所以在先序遍历中,子节点的指针指向不可能是根节点的前驱,所以不可能找到P的前驱;

但如果知道P的父节点F(可建立三叉树),且F的左右儿子为L,R,分以下四种情况讨论:

  • P没有父节点,F不存在为NULL,P没有前驱
  • P的父节点有左右儿子,并且P是左儿子L, 遍历顺序:F ( P ) ( R ); 以P为根节点的先序遍历(P, P的左儿子,P的右儿子);代入F P (P的左儿子) (P的右儿子)R,所以这种情况P的前驱就是父节点;
  • 同理,F没有左儿子,P就是F的右儿子,先序遍历:F ( R ) 代入
    F P (P的左儿子) (P的右儿子),所以这种情况P的前驱就是父节点;
    以此类推F没有右儿子,P就是F的左儿子,也能得到P的前驱就是父节点;
  • P的父节点有左右儿子,并且P是右儿子R, 遍历顺序:F ( L ) ( P );
    P的前驱是F的左儿子先序遍历的最后一个结点。

2.后继

如果p->rtag == 1; p的后继就是p->rchild;

如果p->rtag == 0;P一定有右儿子
  • P也有左儿子,根据先序遍历,P (P的左儿子) (P的右儿子),那么P的后继就是一定是P的左儿子先序遍历的第一个结点,P P的左儿子 (P的左儿子的左儿子)(P的左儿子的右儿子) (P的右儿子),显而易见,P的后继是P的左儿子;
  • 同理P没有左儿子,P的后继就是P的右儿子;

二,后序线索二叉树

同先序一样分析

三,中序线索二叉树

中序线索二叉树,任意一个结点P都能找到对应的前驱,后继

  1. 前驱
    (左 根P 右);

如果P->ltag == 1: 前驱就是 P->lchild

如果P->ltag == 0: 前驱就是 左孩子中序遍历的最后一个结点,要想找到左孩子中序遍历的最后一个结点,我们应该左孩子出发,一直探寻它的右节点,这是因为((P的左儿子的左儿子)P的左儿子 (P的左儿子的右儿子) 根P 右);如果 右节点不存在显然,对应的根节点就是最后一个

//找到以P为根的子树中,最后一个被中序遍历的点
threadTree LastNode(threadTree p){
    while(p->rtag == 0)
        p = p->rchild;
    return p;
}
//找到p的前驱结点
threadTree PreNode(threadTree p){
    if(p->ltag == 0)
        reutrn LastNode(p->lchild);//如果p有左孩子,找到以p左孩子为根节点先序遍历的最后一个节点
    else
    {
        return p->lchild;
    }
    //return p->ltag ? p->lchild : LastNode(p->lchild);
}
  1. 后继

    和前驱同理

如果P->rtag == 0: 后继就是 P右孩子中序遍历的第一个结点,要想找到右孩子中序遍历的第一个结点,我们应该右孩子出发,一直探寻它的左节点,这是因为( 左 根P(P的右儿子的左儿子)P的右儿子 (P的右儿子的右儿子));如果 右节点不存在显然,对应的根节点就是最后一个

//找到以P为根的右子树中,第一个被中序遍历的点
threadTree FirstNode(threadTree p)
{
    while (p->ltag == 0)
        p = p->lchild;
    return p;
}
//找到p的后继结点
threadTree NextNode(threadTree p)
{
    if (p->rtag == 0)
        reutrn LastNode(p->rchild); //如果p有右孩子,找到以p右孩子为根节点中序遍历的第一个节点
    else
    {
        return p->rchild;
    }
    //return p->rtag ? p->rchild : LastNode(p->rchild);
}
  数据结构与算法 最新文章
【力扣106】 从中序与后续遍历序列构造二叉
leetcode 322 零钱兑换
哈希的应用:海量数据处理
动态规划|最短Hamilton路径
华为机试_HJ41 称砝码【中等】【menset】【
【C与数据结构】——寒假提高每日练习Day1
基础算法——堆排序
2023王道数据结构线性表--单链表课后习题部
LeetCode 之 反转链表的一部分
【题解】lintcode必刷50题<有效的括号序列
上一篇文章      下一篇文章      查看所有文章
加:2021-08-29 09:37:13  更:2021-08-29 09:38:28 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/25 22:47:12-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码