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

目录

一、普通树的存储结构

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方式则可以异步发送消…

1.什么是Angular?

Angular Angular 是一个应用设计框架与开发平台&#xff0c;旨在创建高效而精致的单页面应用。 什么是Angular&#xff1f; Angular 是一个基于 TypeScript 构建的开发平台。它包括&#xff1a; 一个基于组件的框架&#xff0c;用于构建可伸缩的 Web 应用。一组完美集成的库&am…

解决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…

odoo16 一个比较复杂的domain

一个比较复杂的domain 今天在做项目管理的二开&#xff0c;碰到一个比较复杂的domain domain"[(user_ids, in, uid),(state, in, (已发布,进行中,待审核))]"domain"[&amp;,|,(user_ids, in, uid),(last_task_user_ids, in, uid),(state, , 待审核)]"需…

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…

【Java并发编程八】synchronized原理

synchronized的基本使用 可以在代码中加入synchronized代码块&#xff0c;也可以在方法的返回值前面加上synchronized声明。一把锁只能同时被一个线程获取&#xff0c;没有获得锁的线程只能等待。每个实例都对应有自己的一把锁&#xff0c;不同实例之间互不影响。synchronized修…

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商…

SpringBoot 注解开发

利用自定义注解&#xff0c;解决问题 例1 自定义注解限制请求 场景&#xff1a;前端发起的频繁的请求&#xff0c;导致服务器压力过大。需要对后端接口进行限流处理&#xff0c;每个接口都需要做限流处理的话就会导致代码冗余&#xff0c;此时就可以利用注解进行解决 非注解形…

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

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

2023年网络安全竞赛—内存取证解析

内存取证 目录 内存取证 解析如下: 任务:内存取证 *任务说明:仅能获取win20230306的IP地址 FTP用户名:user,密码:123456 在服务器中下载内存片段,在内存片段中获取主机信息&

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

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

malloc 和 new的区别

在 C 中&#xff0c;malloc 和 new 都是用于动态分配内存的方法&#xff0c;但它们有一些重要的区别。以下是关于 malloc 和 new 的常见面试内容及答案的总结&#xff1a; 1. 区别&#xff1a; malloc 是 C 语言的函数&#xff0c;而 new 是 C 中的运算符。malloc 只分配内存…

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…