【考研复习】二叉树的特殊存储|三叉链表存储二叉树、一维数组存储二叉树、线索二叉树

文章目录

  • 三叉链表存储二叉树
    • 三叉链表的前序遍历(不使用栈)法一
    • 三叉链表的前序遍历(不使用栈)法二
  • 一维数组存储二叉树
    • 一维数组存储二叉树的先序遍历
  • 线索二叉树的建立
  • 真题演练

三叉链表存储二叉树

三叉链表结构体表示如下图所示:

构造三叉链表方式:

typedef struct node{char data;struct node*parent,*lchild,*rchild;
}BTNode,*BiTree;
BTNode * creattree(BiTree &t){ // 易错点:树的引用char ch;cin>>ch;if(ch=='#'){t=NULL;}else{t=(BTNode*)malloc(sizeof(BTNode));// 易错点:忘记重新创建新结点t->data=ch;t->parent=NULL;t->lchild=NULL;t->rchild=NULL;if(t->lchild) t->lchild->parent=t;if(t->rchild) t->rchild->parent=t;creattree(t->lchild);creattree(t->rchild);}return t;
}

另外设计一个填充函数,函数功能是将所有结点的parent结点填充正确。

void FillParent(BiTree &root){if(root==NULL) return;if(root->lchild) {root->lchild->parent=root;FillParent(root->lchild);}if(root->rchild){root->rchild->parent=root;FillParent(root->rchild);}
}

三叉链表的前序遍历(不使用栈)法一

void PreOrder(BiTree t){   //访问顺序:根左右BTNode *p;while(t){visit(t);//访问根if(t->lchild) t=t->lchild;//找到左下结点,下一次就循环访问左else if(t->rchild) t=t->rchild;//下一次循环访问右else{//如果当前结点既没有左孩子也没有有孩子while(1){//一直往上回溯到有非空的父亲结点、同时找到二叉树的那个“叉”p=t;//p指向根tt=t->parent;//t指向父亲结点if(!t) break;//如果t为空,则说明该节点是空结点,排除这种情况if(t->lchild==p&&t->rchild) break;//如果t的左孩子是p且t的右孩子不为空,跳出while之后到右结点}if(t)t=t->rchild;//往右边访问}}
}

三叉链表的前序遍历(不使用栈)法二

// 【题目】二叉树采用三叉链表的存储结构,试编写
// 不借助栈的非递归中序遍历算法。
// 三叉链表类型定义:
typedef struct TriTNode
{char data;struct TriTNode *parent, *lchild, *rchild;
} TriTNode, *TriTree;void InOrder(TriTree PT, void (*visit)(char))
/* 不使用栈,非递归中序遍历二叉树PT,  */
/* 对每个结点的元素域data调用函数visit */
{TriTree p = PT, pr;while (p){if (p->lchild)p = p->lchild; // 寻找最左下结点else{visit(p->data); // 找到最左下结点并访问if (p->rchild){p = p->rchild; // 若有右子树,转到该子树,继续寻找最左下结点}else{pr = p; // 否则返回其父亲p = p->parent;while (p && (p->lchild != pr || !p->rchild)){                        // 若其不是从左子树回溯来的,或左结点的父亲并没有右孩子if (p->lchild == pr) // 若最左结点的父亲并没有右孩子visit(p->data);  // 直接访问父亲(不用转到右孩子)pr = p;              // 父亲已被访问,故返回上一级p = p->parent;       // 该while循环沿双亲链一直查找,若无右孩子则访问,直至找到第一个有右孩子的结点为止(但不访问该结点,留给下步if语句访问)}if (p){ // 访问父亲,并转到右孩子(经上步while处理,可以确定此时p有右孩子)visit(p->data);p = p->rchild;}}}}
}

一维数组存储二叉树

// 动态输入
void CreateTreeArray(int a[], int n)
{char ch;for (int i = 0; i < n; i++){cin >> ch;a[i] = ch;}
}

一维数组存储二叉树的先序遍历

// 前序遍历
#define Maxsize 50
typedef struct BTNodeArray
{int data[Maxsize];int length;
} BTNodeArray;
void PreOrderArray(BTNodeArray t, int i)
{if (i >= t.length)return;printf("%d", t.data[i]);PreOrderArray(t, i * 2);     // 遍历左子树PreOrderArray(t, i * 2 + 1); // 遍历右子树
}

线索二叉树的建立

线索二叉的的基本结构:

使用中序遍历的顺序进行线索化。代码中有一个难以理解的点,为什么不用p直接找后继,而是使用了前驱结点找后继。实际上,不是不用p找后继,而是从p找不到后继,所以只能间接地找前驱的后继,这样的方式找后继,明白了这点,代码就不难懂了。

//中序遍历线索化
void InOrder(ThreadTree &p,ThreadTree &pre){if(p!=NULL){InOrder(p->lchild,pre);if(p->lchild==NULL){    //只能通过当前结点找前驱p->lchild=pre;p->ltag=1;}if(pre->rchild==NULL){  //只能通过前驱结点找后继pre->rchild=p;pre->rtag=1;}pre=p;InOrder(p->rchild,pre);}return;
}
void InOrderThread(ThreadTree t){ThreadNode *pre=NULL;if(t!=NULL){InOrder(t,pre);pre->rchild=NULL;pre->rtag=1;}
}

真题演练

在这里插入图片描述

//建立三叉链表,
//删除每一个元素为x的结点,以及以他为根的子树且释放相应存储空间
#include<iostream>
using namespace std;void BuildTree(BiTree &t){char ch;cin>>ch;if(ch=='#'){t=NULL;}else{t=(BTNode *)malloc(sizeof(BTNode));t->data=ch;t->parent=NULL;t->lchild=NULL;t->rchild=NULL;if(t->lchild) t->lchild->parent=t;if(t->rchild) t->rchild->parent=t;BuildTree(t->lchild);BuildTree(t->rchild);}
}
void Destory(BiTree t){if(t==NULL) return;if(t->lchild) Destory(t->lchild);if(t->rchild) Destory(t->rchild);free(t);    //释放根节点t=NULL;     //空指针赋值0
}
void DeleteX(BiTree &t,char x){if(t==NULL) return;if(t->data==x) Destory(t);DeleteX(t->lchild,x);DeleteX(t->rchild,x);
}

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

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

相关文章

飞书开发学习笔记(六)-网页应用免登

飞书开发学习笔记(六)-网页应用免登 一.上一例的问题修正 在上一例中&#xff0c;飞书登录查看网页的界面显示是有误的&#xff0c;看了代码&#xff0c;理论上登录成功之后&#xff0c;应该显示用户名等信息。 最后的res.nickName是用户名&#xff0c;res.i18nName.en_us是英…

IntelliJ IDEA 安装 GitHub Copilot插件 (最新)

注意&#xff1a; GitHub Copilot 插件对IDEA最低版本要求是2021.2&#xff0c;建议直接用2023.3&#xff0c;一次到位反正后续要升级的。 各个版本的依赖关系&#xff0c;请参照&#xff1a; ##在线安装&#xff1a; 打开 IntelliJ IDEA扩展商店&#xff0c;输入 "Git…

数据结构-二叉树力扣题

目录 1.相同的树 2.二叉树中查找值为x的节点 3.单值二叉树 4.对称二叉树 5.二叉树的前序遍历 6.另一颗树的子树 层序遍历&#xff1a; 7.二叉树遍历 8.判断二叉树是否是完全二叉树 一个特殊的性质&#xff1a; 1.相同的树 题目链接&#xff1a;力扣&#xff08;LeetC…

新版软考高项试题分析精选(四)

请点击↑关注、收藏&#xff0c;本博客免费为你获取精彩知识分享&#xff01;有惊喜哟&#xff01;&#xff01; 1、一般而言&#xff0c;大型软件系统中实现数据压缩功能&#xff0c;工作在OSI参考模型的&#xff08; &#xff09;。 A.应用层 B.表示层 C.会话层 D.网络层…

【验证码逆向专栏】百某网数字九宫格验证码逆向分析

声明 本文章中所有内容仅供学习交流使用&#xff0c;不用于其他任何目的&#xff0c;不提供完整代码&#xff0c;抓包内容、敏感网址、数据接口等均已做脱敏处理&#xff0c;严禁用于商业用途和非法用途&#xff0c;否则由此产生的一切后果均与作者无关&#xff01; 本文章未…

vue中ref的用法

vue中ref的用法 在项目中使用ref时有时候直接取值,有时候返回的却是一个数组,不知其中缘由,后查了一下ref用法,所以总结一下. 1.绑定在dom元素上时&#xff0c;用起来与id差不多&#xff0c;通过this.$refs来调用: <div id"passCarEchart" ref"passCarEch…

[PyTorch][chapter 63][强化学习-QLearning]

前言&#xff1a; 这里结合走迷宫的例子,重点学习一下QLearning迭代更新算法 0,1,2,3,4 是房间&#xff0c;之间绿色的是代表可以走过去。 5为出口 可以用下图表示 目录&#xff1a; 策略评估 策略改进 迭代算法 走迷宫实现Python 一 策略评估 强化学习最终是为了…

构建Docker基础镜像(ubuntu20.04+python3.9.10+pytorch-gpu-cuda11.8)

文章目录 一、前置条件1.创建 ubuntu 镜像源文件【sources.list】2.下载 python 安装包【Python-3.9.10.tgz】 二、构建方法1.构建目录2.创建DockerFile3.打包镜像 一、前置条件 1.创建 ubuntu 镜像源文件【sources.list】 内容如下 deb http://mirrors.aliyun.com/ubuntu/ …

SQL编写规范【干货】

编写本文档的目的是保证在开发过程中产出高效、格式统一、易阅读、易维护的SQL代码。 1 编写目 2 SQL书写规范 3 SQL编写原则 获取所有软件开发资料&#xff1a;点我获取

【Java 进阶篇】JQuery 遍历:发现元素的魔法之旅

欢迎来到 JQuery 的奇妙世界&#xff0c;一个充满活力和灵感的地方。在这个世界里&#xff0c;我们将一起探讨 JQuery 的遍历功能&#xff0c;这是一个让你轻松发现和操作网页元素的神奇工具。无需太多前端经验&#xff0c;只要有一颗探险的心&#xff0c;你就能在 JQuery 遍历…

智能家居小程序

1、设备 系统板&#xff1a;STM32F103C8T6 温湿度传感器&#xff1a;DHT11 光照度传感器&#xff1a; BH1750 WIFI模块&#xff1a;ESP8266-015 蜂鸣器&#xff1a; 立创EDC画板子&#xff0c;然后微立创下单

【数据结构】希尔排序(最小增量排序)

&#x1f466;个人主页&#xff1a;Weraphael ✍&#x1f3fb;作者简介&#xff1a;目前正在学习c和算法 ✈️专栏&#xff1a;数据结构 &#x1f40b; 希望大家多多支持&#xff0c;咱一起进步&#xff01;&#x1f601; 如果文章有啥瑕疵 希望大佬指点一二 如果文章对你有帮助…

java springboot在当前测试类中添加临时属性 不影响application和其他范围

目前 我们的属性基本都写在 application.yml 里面了 但是 如果 我们只是想做一下临时变量的测试 有没有办法实现呢&#xff1f; 显然是有的 这里 我们还是先在application.yml中去写一个 test属性 下面加个prop 然后 我们尝试在测试类中 获取一下这个属性 直接用 Value 读取…

C语言——求1/1-1/2+1/3-......+1/99-1/100的值

#include<stdio.h> int main() {int i 1;double sum 0;int flage 1;for(i 1;i < 100; i){sumflage*1.0/i;flage -flage; //正负号}printf("%lf\n",sum);return 0; }

场景图形管理-多视图多窗口渲染示例(4)

多视图多窗口渲染示例的代码如程序清单8-6所示 // 多视图多窗口渲染示例 void compositeViewer_8_6(const string &strDataFolder) {// 创建一个CompositeViewer对象osg::ref_ptr<osgViewer::CompositeViewer> viewer new osgViewer::CompositeViewer();// 创建两个…

Outlook关闭过去事件的提醒

Outlook关闭过去事件的提醒 故障现象 最近Outlook中推出的新功能让我们可以选择自动关闭过去事件的提醒。 目前这个功能暂时只向当月通道的Office 365 订阅者发布。 这些用户升级到1810版本后&#xff0c;可以在不想收到已发生事件提醒的时候通过下面的步骤自动忽略过去事件…

day22_mysql

今日内容 零、 复习昨日 一、MySQL 一、约束 1.1 约束 是什么? 约束,即限制,就是通过设置约束,可以限制对数据表数据的插入,删除,更新 怎么做? 约束设置的语法,大部分是 create table 表名( 字段 数据类型(长度) 约束, 字段 数据类型(长度) 约束 );1.1 数据类型 其实数据类型…

在Spring Boot中使用进程内缓存和Cache注解

在Spring Boot中使用内缓存的时候需要预先知道什么是内缓存&#xff0c;使用内缓存的好处。 什么是内缓存 内缓存&#xff08;也称为进程内缓存或本地缓存&#xff09;是指将数据存储在应用程序的内存中&#xff0c;以便在需要时快速访问和检索数据&#xff0c;而无需每次都从…

Jmeter控制RPS

一、前言 ​ RPS (Request Per Second)一般用来衡量服务端的吞吐量&#xff0c;相比于并发模式&#xff0c;更适合用来摸底服务端的性能。我们可以通过使用 JMeter 的常数吞吐量定时器来限制每个线程的RPS。对于RPS&#xff0c;我们可以把他理解为我们的TPS&#xff0c;我们就不…

解决Github上的README无法显示图片

首先感谢博主的思路&#xff1a;思路 最近写了点东西提交到git 发现本地能查看md里的图片用的相对路径&#xff0c;提交到github就看不见&#xff0c;并且发现不只是我自己的仓库看不见&#xff0c;其他人的我也看不见。那就有问题了 解决&#xff1a;正常使用相对路径&…