网站demo要几个人做/广州网络广告推广公司

网站demo要几个人做,广州网络广告推广公司,奔牛网络推广,广告营销模式线索二叉树构造以及遍历算法 线索二叉树(中序遍历版)构造线索二叉树构造双向线索链表遍历中序线索二叉树 线索二叉树(中序遍历版) 中序遍历找到对应结点的前驱(土方法) #mermaid-svg-eunGO5d2GhjLxCn5 {fo…

线索二叉树构造以及遍历算法

  • 线索二叉树(中序遍历版)
    • 构造线索二叉树
    • 构造双向线索链表
    • 遍历中序线索二叉树

线索二叉树(中序遍历版)

中序遍历找到对应结点的前驱(土方法)

visit 函数
q 是否等于 p
传入节点 q
final = pre
pre = q
返回
开始
调用 InOrder T
树 T 是否为空
结束
递归调用 InOrder T->lchild
调用 visit T
递归调用 InOrder T->rchild
visit
typedef struct BiNode{int data;BiNode *lchild, *rchild;
}BiNode, *BiTree;BiNode *p;  // 指向目标节点
BiNode *pre = NULL; // 指向当前访问节点的前驱
BiNode *final = NULL; // 记录最终结果void InOrder(BiTree T){if(T != NULL){InOrder(T -> lchild);visit(T);InOrder(T -> rchild);}
}// 找到目标节点的前驱节点
void visit(BiNode *q){  // q代表当前访问节点if(p == q)final = pre;   // 如果当前访问节点和目标节点一致了,那么pre就是我们需要找的前驱elsepre = q;       // 如果不一致,那么更新前驱节点
}

由上述代码我们可以知道,如果使用土方法来寻找目标节点的前驱节点,那么每找一次,就需要对二叉树进行一次遍历,这样对资源的浪费是不言而喻的,所以我们需要采用线索二叉树来更加快速地寻找对应节点的前驱后继,通过线索二叉树,我们可以实现对二叉树的随机访问。

问题1:为什么在visit函数中不需要对q进行迭代?

回答1:因为 q q q的迭代是在 I n O r d e r InOrder InOrder中进行的,在每一次对 I n O r d e r InOrder InOrder的递归中,传入 v i s i t visit visit的节点会不会·不断变化,也就实现了对 q q q的迭代。

线索二叉树实际就是用空的 n + 1 个空指针指向直接前驱和直接后继。如果一个节点的左孩子为空,则左孩子指针指向当前节点的前驱,改 l t a g ltag ltag为1;如果一个节点的右孩子为空,则用右孩子指针指向当前节点的后继,改 r t a g rtag rtag为1。

lchildltagdatartagrchild
指示左孩子00指示右孩子
指示直接前驱11指示直接后继
// 线索二叉树的存储结构
typedef struct ThreadTree{int data;struct ThreadTree *lchild, *rchild;int ltag, rtag;
}ThreadNode, *ThreadTree;

构造线索二叉树

通过中序遍历对二叉树线索化

InThread函数
p 是否为空?
传入 p 和 pre
返回
递归调用 InThread p->lchild, pre
p->lchild 是否为空?
p->lchild = pre p->ltag = 1
不做操作
pre 是否非空且 pre->rchild 是否为空?
pre->rchild = p pre->rtag = 1
不做操作
pre = p
递归调用 InThread p->rchild, pre
开始
调用 CreateInThread T
树 T 是否为空?
结束
初始化 pre = NULL
调用 InThread T, pre
pre->rchild = NULL pre->rtag = 1
void InThread(ThreadTree &p, ThreadTree &pre){ // p是当前访问节点,pre为当前访问节点的前驱if(p != NULL){InThread(p -> lchild);if(p -> lchild == NULL){  // 如果左孩子为空,则更新左孩子为前驱,ltag为1p -> lchild = pre;ltag = 1;}if(pre != NULL && pre -> rchild == NULL){ // 若前驱节点非空且其右子树为空,则更新其右孩子为后继,rtag为1pre -> rchild = p;pre -> rtag = 1;}pre = p;InThread(p -> rchild);}
}
void CreateInThread(ThreadTree T){Thread pre = NULL;if(T != NULL){InThread(T, pre);pre -> rchild = NULL; // 处理最后一个节点pre -> rtag = 1;}
}

问题2:为什么在创建二叉树的时候需要判断pre是否为空?

回答2为了避免空指针引用,我们在创建线索二叉树的时候,会把pre初始化为NULL(也就是其实并没有这个节点),因为第一个节点没有直接的前驱,而如果我们不对空指针进行判断的话,那么pre的后继就会是当前节点p,那么究竟谁才是第一个节点呢?运行起来就会导致程序崩溃。只有当pre不为空时,才有意义去判断其右子树是否为空,为它建立线索二叉树才有意义。

构造双向线索链表

但是这样的线索二叉树还是存在一些问题,比如没有办法从第一个节点直接遍历到最后一个节点,为此我们可以建立一个头节点,让其lchild指向二叉树的根节点,其rchild指向中序遍历时访问的最后一个节点。令中序遍历的第一个节点的lchild指向头节点,也就是第一个节点的前驱不再是NULL,而是head;令中序遍历的最后一个节点的rchild指向头节点,也就是最后一个节点的后继也不再是NULL,而是head。这样一来,我们就获得了一个双向线索链表。

InThread函数
p 是否为空?
传入 p 和 pre
返回
递归调用 InThread p->lchild, pre
p->lchild 是否为空?
p->lchild = pre p->ltag = 1
不做操作
pre 是否非空且 pre->rchild 是否为空?
pre->rchild = p pre->rtag = 1
不做操作
pre = p
递归调用 InThread p->rchild, pre
开始
调用 CreateInThread T
分配头节点 head
head 分配成功?
结束
设置 head->ltag = 0
设置 head->rtag = 1
设置 head->rchild = head
T 是否为空?
设置 head->lchild = head
设置 head->lchild = T
初始化 pre = head
调用 InThread T, pre
设置 pre->rchild = head pre->rtag = 1
初始化 first = head->lchild
first->ltag == 0?
first = first->lchild
设置 first->lchild = head
void InThread(ThreadTree &p, ThreadTree &pre){ // p是当前访问节点,pre为当前访问节点的前驱if(p != NULL){InThread(p -> lchild);if(p -> lchild == NULL){  // 如果左孩子为空,则更新左孩子为前驱,ltag为1p -> lchild = pre;ltag = 1;}if(pre != NULL && pre -> rchild == NULL){ // 若前驱节点非空且其右子树为空,则更新其右孩子为后继,rtag为1pre -> rchild = p;pre -> rtag = 1;}pre = p;InThread(p -> rchild);}
}
void CreateInThread(ThreadTree T){ThreadNode *head = (ThreadTree*)malloc(sizeof(ThreadTree));if(head == NULL)return ;head -> ltag = 0; // 指向根节点head -> rtag = 1; // 指向最后一个节点head -> rchild = head; // 初始化右指针指向自己if(T == NULL){head -> lchild = head;}else {head -> lchild = T;ThreadTree pre = head;InTread(T, pre);// 处理最后一个节点pre -> rchild = head;pre -> rtag = 1;// 处理第一个节点ThreadNode *first = head -> lchild; // 初始化第一个节点为根节点,方便找到第一个节点// 寻找中序遍历的第一个节点while(first -> ltag == 0) // 如果lchild是指向左孩子则迭代first = first -> lchild;first -> lchild = head;}
}

遍历中序线索二叉树

只要先找到序列中的第一个节点,然后依次找节点的后继,直到其后继为空便可完成遍历;

1. 求第一个节点

ThreadNode *FirstNode(ThreadNode *p){while(p -> ltag == 0) p = p -> lchild;return p;
}

2. 求中序线索二叉树中节点p在中序序列下的后继

ThreadNode *NextNode(ThreadNode *p){if(p -> rtag == 0) return FirstNode(p -> rchild); // 右子树中最左下节点else return p -> rchild;
}

3. 求中序线索二叉树的最后一个节点

ThreadNode *LastNode(ThreadNode *p){while(p -> rtag == 0) p = p -> rchild;return p;
}

4. 求节点p前驱

ThreadNode *PreNode(ThreadNode *p){if(p -> ltag == 0) return LastNode(p -> lchild);return p;
}

利用上述1.2.两个算法,我们可以写出不含头节点的中序线索二叉树的中序遍历算法:

void InOrder(ThreadNode *T){for(ThreadNode *p = FirstNode(T); p != NULL; p = NextNode(p))visit(p); // 访问节点,可自由设定
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/897586.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

基于SpringBoot的“体育购物商城”的设计与实现(源码+数据库+文档+PPT)

基于SpringBoot的“体育购物商城”的设计与实现(源码数据库文档PPT) 开发语言:Java 数据库:MySQL 技术:SpringBoot 工具:IDEA/Ecilpse、Navicat、Maven 系统展示 系统总体模块设计 前台用户登录界面 系统首页界面…

go context学习

1.Context接口2.emptyCtx3.Deadline()方法4.Done()方法5.Err方法6.Value方法()7.contex应用场景8.其他context方法 1.Context接口 Context接口只有四个方法,以下是context源码。 type Context interface {Deadline() (deadline time.Time, …

在VMware Workstation Pro上轻松部署CentOS7 Linux虚拟机

首先我们需要下载VM虚拟机和Centos7的镜像 下载并安装VMware Workstation Pro 访问VMware Workstation Pro官网下载 https://www.vmware.com/ 第二步:下载centos7镜像 访问centos官网下载 https://www.centos.org/ 开始部署Centos7 点击创建新的虚拟机 这里是Cen…

Android AudioFlinger(五)—— 揭开AudioMixer面纱

前言: 在 Android 音频系统中,AudioMixer 是音频框架中一个关键的组件,用于处理多路音频流的混音操作。它主要存在于音频回放路径中,是 AudioFlinger 服务的一部分。 上一节我们讲threadloop的时候,提到了一个函数pr…

从0开始的操作系统手搓教程27:下一步,实现我们的用户进程

目录 第一步:添加用户进程虚拟空间 准备冲向我们的特权级3(用户特权级) 讨论下我们创建用户线程的基本步骤 更加详细的分析代码 用户进程的视图 说一说BSS段 继续看process.c中的函数 添加用户线程激活 现在,我们做好了TSS…

Node 使用 SSE 结合redis 推送数据(echarts 图表实时更新)

1、实时通信有哪些实现方式? 特性轮询(Polling)WebSocketSSE (Server-Sent Events)通信方向单向(客户端 → 服务端)双向(客户端 ↔ 服务端)单向(服务端 → 客户端)连接方…

Android Native 之 文件系统挂载

一、文件系统挂载流程概述 二、文件系统挂载流程细节 1、Init启动阶段 众所周知,init进程为android系统的第一个进程,也是native世界的开端,要想让整个android世界能够稳定的运行,文件系统的创建和初始化是必不可少的&#xff…

Redis--Set类型

目录 一、引言 二、介绍 三、命令 1.sadd,smembers,sismember 2.spop,srandmember 3.smove,srem 4.sinter,sinterstore 5.sunion,sunionstore,sdiff,sdiffstore 四、内部编码 1.intset 2.hashtable 五、应用场景 1.使用Set保存用…

Faster R-CNN原理详解以及Pytorch实现模型训练与推理

《------往期经典推荐------》 一、AI应用软件开发实战专栏【链接】 项目名称项目名称1.【人脸识别与管理系统开发】2.【车牌识别与自动收费管理系统开发】3.【手势识别系统开发】4.【人脸面部活体检测系统开发】5.【图片风格快速迁移软件开发】6.【人脸表表情识别系统】7.【…

使用dockerfile创建镜像

1.什么是Dockerfile Dockerfile 是一个用于指导 Docker 镜像构建过程的脚本文件。它通过一系列指令来详细描述了构建镜像所需的步骤和配置细节。利用 Dockerfile,我们可以精确地设定容器的运行环境,安装必要的软件,复制项目文件,…

大脑宏观结构中的富集俱乐部:图论分析视角

摘要 大脑是一个高度复杂的网络。越来越多的证据支持大脑网络中一组重要脑区的关键作用,这些脑区通常被称为大脑的“核心”或“枢纽”区域。这些区域不仅能量消耗较高,而且在神经信息传递方面的效率也极高,因此被称为“富集俱乐部”。富集俱乐…

Redis7——进阶篇(五)

前言:此篇文章系本人学习过程中记录下来的笔记,里面难免会有不少欠缺的地方,诚心期待大家多多给予指教。 基础篇: Redis(一)Redis(二)Redis(三)Redis&#x…

光谱相机检测肉类新鲜度的原理

光谱相机通过分析肉类样本在特定波长范围内的光谱反射特性,结合化学与生物指标的变化规律,实现对其新鲜度的无损检测。其核心原理可概括为以下方面: 一、光谱特征与物质成分的关联性 ‌物质特异性吸收/反射‌ 不同化学成分(如水分…

c#面试题整理9

1.遍历xml文档 2.解释一下这段 String s new String("xyz"); 这段在C#平台中,编译失败 3.说明一下抽象类 抽象类可以有构造函数 抽象类不能是静态和密封的类,密封的类表示无法继承,抽象类本身就不可实例化,加不好…

《React 属性与状态江湖:从验证到表单受控的实战探险》

属性初识 属性能解决两个大问题&#xff1a;通信和复用 props.js: import React, { Component } from react import Navbar from ./Navbarexport default class App extends Component {state {a:100}render() {return (<div><div><h2>首页</h2>&l…

Qwen/QwQ-32B 基础模型上构建agent实现ppt自动生成

关心Qwen/QwQ-32B 性能测试结果可以参考下 https://zhuanlan.zhihu.com/p/28600079208https://zhuanlan.zhihu.com/p/28600079208 官方宣传上是该模型性能比肩满血版 DeepSeek-R1&#xff08;671B&#xff09;&#xff01; 我们实现一个 使用Qwen/QwQ-32B 自动生成 PowerPoi…

[杂学笔记] TCP和UDP的区别,对http接口解释 , Cookie和Session的区别 ,http和https的区别 , 智能指针 ,断点续传

文章目录 1. TCP和UDP的区别2. 对http接口解释3. Cookie和Session的区别4. http和https的区别5. 智能指针6.断点续传 1. TCP和UDP的区别 tcp的特点&#xff1a; 面向连接&#xff0c;可靠性高&#xff0c;全双工&#xff0c;面向字节流udp特点&#xff1a;无连接&#xff0c;不…

Matlab中快速查找元素索引号

1、背景介绍 在算法设计过程中&#xff0c;有时候需要从一维/二维数组中&#xff0c;快速查找是否某个元素&#xff0c;以及该元素所在的位置。如一维矩阵[1 2 3 4 5 6 6 7 8]所示&#xff0c;元素6所在的位置为6 7。 2、函数测试 matlab中函数find()可以快速查找到指定元素所…

【DuodooTEKr 】多度科技 以开源之力,驱动企业数字化转型

多度科技 背景 / Background 在全球产业链重构与国内经济双循环的浪潮下&#xff0c;中国制造业与贸易企业正面临数字化升级的迫切需求。开源技术作为数字化转型的基石&#xff0c;不仅能打破技术壁垒、降低企业成本&#xff0c;更能通过协作创新加速产业智能化进程。 多度科技…

【HarmonyOS Next】鸿蒙应用故障处理思路详解

【HarmonyOS Next】鸿蒙应用崩溃处理思路详解 一、崩溃问题发现后定位 1. 崩溃现象&#xff1a; 常见的崩溃问题表现为&#xff0c;应用操作后白屏闪退&#xff0c;或者应用显示无响应卡死。 2.定位问题&#xff1a; 发现崩溃后&#xff0c;我们首先需要了解复现步骤&#x…