数据结构树与二叉树的实现

目录

一、普通树的存储结构

1、双亲表示法

2.孩子表示法

二、二叉树

1.二叉树的顺序存储(必须是完全二叉树,否则很浪费空间)

1)结构体

2.二叉树的链式存储

1)结构体

2)操作

1.创建一颗二叉树

2.创建一个结点

3.二叉树的前序遍历

a.递归实现

b.非递归,使用栈

4.二叉树的中序遍历

a.递归实现

b.非递归实现

5.二叉树的后序遍历

a.递归实现

b.非递归实现

6.二叉树的层次遍历:使用队列

三、线索二叉树

1.先序线索化

2.中序线索化

3.后序线索化

4.拓展,中序线索二叉树中

1)找到以p为根,第一个为中序遍历的结点,其实就是最左边的叶节点

2)找到p的后继

3)能找到后继,就可以不使用递归来遍历了,能得到中序遍历结果

4)找到以p为根结点,最后一个被中序遍历的结点,也就是p最右边的叶子结点

5)找到p的前驱

6)逆序中序遍历

5.拓展,先序二叉树中

1)寻找后继

2)不能知道找到前驱,除非能直接找到父节点,然后再讨论

6.拓展,后续二叉树中

1)寻找前驱

2)找不到后继,除非能找到父节点,再讨论

四、二叉排序树

1.结构体

2.操作函数

1)创建一颗二叉排序树

2)创建一颗二叉排序结点

3)查找关键值所对应结点

a.递归

b.非递归

4)插入关键值

5)构造一颗二叉排序树,其实就是不断插入的过程


一、普通树的存储结构

1、双亲表示法

typedef  struct{ElemType data;int parent;
}PTNode;typedef  struct{PTNode nodes[MAXSIZE];int n;  //结点数
}PTree;

2.孩子表示法

struct CTNode{int child; //孩子在数组中的下标CTNode *next;
};typedef  struct {ElemType data;CTNode *firstChild;
}CTBox;typedef  struct{CTBox nodes[MAXSIZE];int n,r;//结点数、根的下标
}CTree;

二、二叉树

1.二叉树的顺序存储(必须是完全二叉树,否则很浪费空间)

1)结构体

struct TreeNode{ElemType value;bool isEmpty;
};TreeNode t[MAXSIZE]; //一般从下标为1开始存储,为了和下标对应起来,方便查找孩子//顺序存储初始化将所有的isEmpty变为TRUE//左孩子为2i 右孩子为2i+1  父节点为i/2//i>n/2就是叶子结点

2.二叉树的链式存储

1)结构体

//二叉树的链式存储
typedef  struct BiTNode{ElemType data;BiTNode *lchild,*rchild;
}BiTNode,*BTree;

2)操作

1.创建一颗二叉树

BTree CreatBTree(ElemType rootdata)
{BiTNode *root = (BiTNode*)malloc(sizeof(BiTNode));root->data=rootdata;root->lchild=NULL;root->rchild=NULL;return  root;
}

2.创建一个结点

BiTNode *CreatBiTNode(ElemType data)
{BiTNode* NewNode = (BiTNode*)malloc(sizeof(BiTNode));NewNode->data=data;NewNode->lchild=NULL;NewNode->rchild=NULL;return  NewNode;
}

3.二叉树的前序遍历

a.递归实现
void PreOrder(BTree T)
{if(T!=NULL){visit(T);PreOrder(T->lchild);PreOrder(T->rchild);}
}
b.非递归,使用栈
//会使用栈
void PreOrder1(BTree T)
{SqStack s;InitStack(s);BTree p =T;while (p||!StackEmpty(s)) {if(p){visit(p);push(s,p);p=p->lchild;}else {pop(s,p);p=p->rchild;}}
}

4.二叉树的中序遍历

a.递归实现
void InOrder(BTree T)
{if(T!=NULL){InOrder(T->lchild);visit(T);InOrder(T->rchild);}
}
b.非递归实现
void InOrder1(BTree T)
{SqStack s;InitStack(s);BTree p = T;while (p||!StackEmpty(s)) {if(p){push(s,p);p=p->lchild;}else {pop(s,p);visit(p);p=p->rchild;}}
}

5.二叉树的后序遍历

a.递归实现
void PostOrder(BTree T)
{if(T!=NULL){PostOrder(T->lchild);PostOrder(T->rchild);visit(T);}
}
b.非递归实现
void PostOrder1(BTree T)
{SqStack s;InitStack(s);BTree p = T;BTree r=NULL;while (p||!StackEmpty(s)) {if(p){push(s,p);p=p->lchild;}else {GetTop(s,p);if(p->rchild!=r&&p->rchild)p=p->rchild;else {pop(s,p);visit(p);r=p;p=NULL;}}}
}

6.二叉树的层次遍历:使用队列


void LevelOrder(BTree T)
{LinkQueue Q;InitLinkQueue(Q);BTree p;EnLinkQueue(Q,T);while (!LinkQueueEmpty(Q)) {DeLinkQueue(Q,p);visit(p);if(p->lchild!=NULL)EnLinkQueue(Q,p->lchild);if(p->rchild!=NULL)EnLinkQueue(Q,p->rchild);}
}

三、线索二叉树

1.先序线索化

void PreThread(ThreadTree T, ThreadTree &pre)
{if(T!=NULL){if(T->lchild==NULL){T->lchild=pre;T->ltag=1;}if(pre!=NULL and pre->rchild==NULL){pre->rchild=T;pre->rtag=1;}pre=T;if(T->ltag==0)PreThread(T->lchild,pre);PreThread(T->rchild,pre);}
}void CreatPreThread(ThreadTree T)
{ThreadTree pre= NULL;if(T!=NULL){PreThread(T,pre);pre->rchild=NULL;pre->rtag=1;}
}

2.中序线索化

void InThread(ThreadTree T,ThreadTree &pre)
{if(T!=NULL){InThread(T->lchild,pre);if(T->lchild==NULL){T->lchild=pre;T->ltag=1;}if(pre!=NULL and pre->rchild==NULL){pre->rchild=T;pre->rtag=1;}pre=T;InThread(T->rchild,pre);}}void CreatInThread(ThreadTree T)
{ThreadTree pre= NULL;if(T!=NULL){InThread(T,pre);pre->rchild=NULL;pre->rtag=1;}
}

3.后序线索化

void PostThread(ThreadTree T, ThreadTree &pre)
{if(T!=NULL){PostThread(T->lchild,pre);PostThread(T->rchild,pre);if(T->lchild==NULL){T->lchild=pre;T->ltag=1;}if(pre!=NULL and pre->rchild==NULL){pre->rchild=T;pre->rtag=1;}pre=T;}
}void CreatPostThread(ThreadTree T)
{ThreadTree pre= NULL;if(T!=NULL){PostThread(T,pre);pre->rchild=NULL;pre->rtag=1;}
}

4.拓展,中序线索二叉树中

1)找到以p为根,第一个为中序遍历的结点,其实就是最左边的叶节点

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)能找到后继,就可以不使用递归来遍历了,能得到中序遍历结果

void InOrder1(ThreadTree T)
{for(ThreadNode *p = FirstNode(T);p!=NULL;p=NextNode(p)){visit_Thread(p);}
}

4)找到以p为根结点,最后一个被中序遍历的结点,也就是p最右边的叶子结点

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

5)找到p的前驱

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

6)逆序中序遍历

void RevInOrder(ThreadTree T)
{for(ThreadNode *p = LastNode(T);p!=NULL;p=preNode(p)){visit_Thread(p);}
}

5.拓展,先序二叉树中

1)寻找后继

ThreadNode *NextNode_pre(ThreadNode *p)
{if(p->rtag==0){if(p->lchild!=NULL)return p->lchild;if(p->rchild!=NULL)return p->rchild;}else {return p->rchild;}
}

2)不能知道找到前驱,除非能直接找到父节点,然后再讨论

6.拓展,后续二叉树中

1)寻找前驱

ThreadNode *preNode_post(ThreadNode *p)
{if(p->ltag==1){return p->lchild;}else {if(p->rchild!=NULL)return p->rchild;else {return p->lchild;}}
}

2)找不到后继,除非能找到父节点,再讨论

四、二叉排序树

1.结构体

typedef  struct BSTNode{ElemType data;BSTNode *lchild,*rchild;
}BSTNode,*BSTree;

2.操作函数

1)创建一颗二叉排序树

BSTree CreatBSTree(ElemType rootdata)
{BSTNode *NewNode = (BSTNode*)malloc(sizeof (BSTNode));NewNode->data=rootdata;NewNode->lchild=NULL;NewNode->rchild=NULL;return  NewNode;
}

2)创建一颗二叉排序结点

BSTNode *CreatBSTNode(ElemType data)
{BSTNode *NewNode = (BSTNode*)malloc(sizeof (BSTNode));NewNode->data=data;NewNode->lchild=NULL;NewNode->rchild=NULL;return  NewNode;
}

3)查找关键值所对应结点

a.递归
BSTNode *BSTSearch(BSTree bt, ElemTpye key)
{if(bt==NULL)return  NULL;if(bt->data==key)return bt;else if (bt->data>key) {return BSTSearch(bt->lchild,key);}else {return  BSTSearch(bt->rchild,key);}
}
b.非递归
BSTNode *BSTSearch(BSTree bt, ElemType key)
{while(bt!=NULL and key!=bt->data){if(key<bt->data)bt=bt->lchild;else {bt=bt->rchild;}}return bt;
}

4)插入关键值

bool BSTInsert(BSTree &bt, ElemType key)
{if(bt==NULL){BSTNode *Newnode = CreatBSTNode(key);bt=Newnode;return true;}if(bt->data==key){return false;}else if(bt->data>key){return BSTInsert(bt->lchild,key);}else {return BSTInsert(bt->rchild,key);}}

5)构造一颗二叉排序树,其实就是不断插入的过程

void CreatBST(BSTree &bt, int key[], int n)//key[] 关键字数组,n 关键字数组长度
{bt = NULL;for (int i=0;i<n;i++) {BSTInsert(bt,key[i]);}
}

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

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

相关文章

Linux内核mmap内存映射详解及例子实现

mmap在linux哪里&#xff1f; 什么是mmap&#xff1f; 上图说了&#xff0c;mmap是操作这些设备的一种方法&#xff0c;所谓操作设备&#xff0c;比如IO端口&#xff08;点亮一个LED&#xff09;、LCD控制器、磁盘控制器&#xff0c;实际上就是往设备的物理地址读写数据。 但…

【Zabbix监控二】之zabbix自定义监控内容案例(自动发现、自动注册)

一、自定义监控内容 案例&#xff1a;自定义监控客户端服务器登录的人数 需求&#xff1a;限制登录人数不超过3个人&#xff0c;超过5个人就发出报警 1、在客户端创建自定义key 明确需要执行的linux命令 创建zabbix监控项配置文件&#xff0c;用于自定义Key #在zabbix的配…

SMART PLC数值积分器功能块(矩形+梯形积分法完整源代码)

PLC的数值积分器算法也可以参考下面文章链接: PLC算法系列之数值积分器(Integrator)-CSDN博客文章浏览阅读1.5k次,点赞3次,收藏3次。数值积分和微分在工程上的重要意义不用多说,闭环控制的PID控制器就是积分和微分信号的应用。流量累加也会用到。有关积分运算在流量累加上…

算法-二叉树-简单-二叉树的遍历

记录一下算法题的学习6 首先我们要回忆一下怎么样遍历一个树&#xff1a; 三种遍历概念 先序遍历&#xff1a;先访问根节点&#xff0c;再访问左子树&#xff0c;最后访问右子树。 后序遍历&#xff1a;先左子树&#xff0c;再右子树&#xff0c;最后根节点。 中序遍历&…

kafka原理看这一篇就够了

为何使用消息队列 异步。接口方式实现多个系统协作&#xff0c;如图A系统作为用户请求接收方&#xff0c;需要调用多个系统的接口&#xff0c;这些接口还有可能是在A系统里同步调用&#xff0c;所以最后的接口耗时是多个系统接口耗时的总和&#xff1b;mq方式则可以异步发送消…

解决ubuntu23.10 wifi不能使用的问题

解决ubuntu23.10 wifi不能使用的问题 今天升级到了ubuntu23.10之后&#xff0c;wifi不能使用。 参考此视频解决了问题&#xff1a; https://www.youtube.com/watch?appdesktop&vn92O8rNKVb0 sudo lshw -class networkcd /etc/pm/sleep.dlssudo touch configsudo gedit co…

Java制作俄罗斯方块

Java俄罗斯方块小游戏 import javax.swing.*; import java.awt.*; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.KeyEvent; import java.awt.event.KeyListener; import java.util.ArrayList; import java.util.List; imp…

C#,怎么修改(VS)Visual Studio 2022支持的C#版本

一些文字来自于 Microsoft . &#xff08;只需要读下面的红色文字即可&#xff01;&#xff09; 1 C# 语言版本控制 最新的 C# 编译器根据项目的一个或多个目标框架确定默认语言版本。 Visual Studio 不提供用于更改值的 UI&#xff0c;但可以通过编辑 .csproj 文件来更改值。…

1688阿里巴巴官方开放平台API接口获取商品详情、商品规格信息列表、价格、宝贝详情数据调用示例说明

商品详情API接口在电商平台和购物应用中的作用非常重要。它提供了获取商品详细信息的能力&#xff0c;帮助用户了解和选择合适的商品&#xff0c;同时也支持开发者进行竞品分析、市场研究和推广营销等工作&#xff0c;以提高用户体验和促进销售增长。 1688.item_get-获得1688商…

单链表的实现(Single Linked List)---直接拿下!

单链表的实现&#xff08;Single Linked List&#xff09;—直接拿下&#xff01; 文章目录 单链表的实现&#xff08;Single Linked List&#xff09;---直接拿下&#xff01;一、单链表的模型二、代码实现&#xff0c;接口函数实现①初始化②打印链表③创建一个结点④尾插⑤尾…

Unity 场景烘培 ——unity Post-Processing后处理1(四)

提示&#xff1a;文章有错误的地方&#xff0c;还望诸位大神不吝指教&#xff01; 文章目录 前言一、Post-Processing是什么&#xff1f;二、安装使用Post-Processing1.安装Post-Processing2.使用Post-Processing&#xff08;1&#xff09;.添加Post-process Volume&#xff08…

Flutter 3.16 中带来的更新

Flutter 3.16 中带来的更新 目 录 1. 概述2. 框架更新2.1 Material 3 成为新默认2.2 支持 Material 3 动画2.3 TextScaler2.4 SelectionArea 更新2.5 MatrixTransition 动画2.6 滚动更新2.7 在编辑菜单中添加附加选项2.8 PaintPattern 添加到 flutter_test 3. 引擎更新&#xf…

文件隐藏 [极客大挑战 2019]Secret File1

打开题目 查看源代码发现有一个可疑的php 访问一下看看 点一下secret 得到如下页面 响应时间太短我们根本看不清什么东西&#xff0c;那我们尝试bp抓包一下看看 提示有个secr3t.php 访问一下 得到 我们看见了flag.php 访问一下可是什么都没有 那我们就进行代码审计 $file$_…

Servlet---上传文件

文章目录 上传文件的方法上传文件的示例前端代码示例后端代码示例 上传文件的方法 上传文件的示例 前端代码示例 <body><form action"upload" method"post" enctype"multipart/form-data"><input type"file" name&qu…

2023年中国地产SaaS分类、产业链及市场规模分析[图]

SaaS是一种基于云计算技术&#xff0c;通过订阅的方式向互联网向客户提供访问权限以获取计算资源的一项软件即服务。地产SaaS则是SaaS的具体应用&#xff0c;提供了一个线上平台&#xff0c;用于协助房地产供应商与购房者、建筑承建商、材料供应商及房地产资产管理公司之间的协…

【Linux网络】详解使用http和ftp搭建yum仓库,以及yum网络源优化

目录 一、回顾yum的原理 1.1yum简介 yum安装的底层原理&#xff1a; yum的好处&#xff1a; 二、学习yum的配置文件及命令 1、yum的配置文件 2、yum的相关命令详解 3、yum的命令相关案例 三、搭建yum仓库的方式 1、本地yum仓库建立 2、通过http搭建内网的yum仓库 3、…

Sentinel 热点规则 (ParamFlowRule)

Sentinel 是面向分布式、多语言异构化服务架构的流量治理组件&#xff0c;主要以流量为切入点&#xff0c;从流量路由、流量控制、流量整形、熔断降级、系统自适应过载保护、热点流量防护等多个维度来帮助开发者保障微服务的稳定性。 SpringbootDubboNacos 集成 Sentinel&…

Navicat for mysql 无法连接到虚拟机的linux系统下的mysql

原创/朱季谦 最近在linux Centos7版本的虚拟机上安装了一个MySql数据库&#xff0c;发现本地可以正常ping通虚拟机&#xff0c;但Navicat则无法正常连接到虚拟机里的MySql数据库&#xff0c;经过一番琢磨&#xff0c;发现解决这个问题的方式&#xff0c;很简单&#xff0c;总共…

Appium移动自动化测试--安装Appium

Appium 自动化测试是很早之前就想学习和研究的技术了&#xff0c;可是一直抽不出一块完整的时间来做这件事儿。现在终于有了。 反观各种互联网的招聘移动测试成了主流&#xff0c;如果再不去学习移动自动化测试技术将会被淘汰。 web自动化测试的路线是这样的&#xff1a;编程语…

springboot--单元测试

单元测试 前言1、写测试要用的类2、写测试要用的类3、运行测试类4、spring-boot-starter-test默认提供了以下库4.1 junit54.1.1 DisplayName:为测试类或者测试方法设置展示名称4.1.2 BeforeAll&#xff1a;所有测试方法运行之前先运行这个4.1.3 BeforeEach&#xff1a;每个测试…