当前位置: 首页 > news >正文

专业的网站建设与优化天台网站建设

专业的网站建设与优化,天台网站建设,提升网站知名度,seo推广二叉树 二叉树的定义 二叉树是一种特殊的树型结构,它的特点是每个结点最多只有两颗子树(即二叉树中不存在度大于2的结点),且二叉树的子树有左右之分,其次序不能任意颠倒。 ⼆叉的意思是这种树的每⼀个结点最多只有两…

二叉树

二叉树的定义

二叉树是一种特殊的树型结构,它的特点是每个结点最多只有两颗子树(即二叉树中不存在度大于2的结点),且二叉树的子树有左右之分,其次序不能任意颠倒。

⼆叉的意思是这种树的每⼀个结点最多只有两个孩⼦结点。注意这⾥是多有两个孩⼦,也可能没有孩⼦或者是只有⼀个孩⼦。

⼆叉树结点的两个孩⼦,⼀个被称为左孩⼦,⼀个被称为右孩⼦。其顺序是固定的,就像⼈的左⼿和右⼿,不能颠倒混淆。

特殊的二叉树

满二叉树

一棵二叉树所有非叶子结点都存在左右孩子,并且所有叶子结点都在同一层级上,那么这棵树就是满二叉树。

完全二叉树

在满二叉树的基础上,从最底层最右边开始,连续去掉若干个结点,那么就形成了完全二叉树。

除了上述两种二叉树,还存在堆、二叉排序树等特殊的二叉树。

二叉树的存储

根据定义,二叉树是特殊类型的树,因此可以使用树的存储方式来存储二叉树。在此基础上,标记左右子树即可。

  • 比如使用vector数组存储时,先尾插左孩子再尾插右孩子。这样输出时,就可以按照左孩子、右孩子的顺序输出。
  • 比如使用链式前向星存储时,先头插左孩子再头插右孩子。注意,此时将会按照右孩子、左孩子的顺序输出。

但是,由于二叉树结构的特殊性,我们可以使用更符合其特性的存储方式:顺序存储链式存储

顺序存储

顺序存储是指使用数组来存储二叉树。对于完全二叉树,我们可以使用数组来存储。并且此时可以利用下标来计算左右孩子和父亲:

如果父存在,其下标为i/2;
如果左孩子存在,其下标为2i;
如果右孩子存在,其下标为2
i+1;

当然,非完全二叉树也可以使用顺序存储,但是此时需要补全空结点,使其变为完全二叉树。

再来考虑其最差情况:如果是右斜树即每一个结点只有右孩子,存在4个结点,那么此时需要使用大小为24 - 1的数组来存储。会造成存储空间的极大浪费。因此,顺序存储一般只适用于完全二叉树或者满二叉树。

链式存储

在竞赛中,我们这里的链式存储依然是静态实现

同时,在竞赛中,给定的树结构通常是有编号的,因此我们可以创建两个数组:l[]用于存储左孩子,r[]用于存储右孩子。其中,l[i]表示结点i的左孩子,r[i]表示结点i的右孩子。

注意,这里的编号是指结点的编号,而不是结点的值。

链式存储的优点是可以存储任意形状的二叉树,并且不需要补全空结点。

题目描述

有一个n( n <=106 )个结点的二叉树。给出每个结点的两个孩子结点的编号,建立一颗二叉树(根结点编号为1),求这棵树的深度。

输入描述

第一行一个整数n,表示n个结点。
接下来n行,第i行两个整数l和r,表示第i个结点的左孩子和右孩子的编号。

#include <iostream>
using namespace std;const int N = 1e6 + 10;int l[N],r[N];int main(){int n;cin >> n;for(int i = 1;i <= n;i++){cin >> l[i] >> r[i];}return 0;
}

二叉树的遍历

基于上一章,二叉树同树一样,存在深度优先遍历(DFS)和宽度优先遍历(BFS)两种遍历方式。

深度优先遍历(DFS)

不同于树的深度优先遍历,二叉树的深度优先遍历有三种遍历方式:

  • 前序遍历:先序遍历根结点,再先序遍历左子树,最后先序遍历右子树。
  • 中序遍历:中序遍历左子树,再中序遍历根结点,最后中序遍历右子树。
  • 后序遍历:后序遍历左子树,再后序遍历右子树,最后后序遍历根结点。

简单来说,前序遍历就是按照根、左、右的顺序遍历;中序遍历就是按照左、根、右的顺序遍历;后序遍历就是按照左、右、根的顺序遍历。

再简言之,三种遍历都是从根到子、先左再右的查找顺序之大前提下,前序遍历就是访问到结点就输出;中序遍历先找到并输出左孩子及其子树(子树中依旧先找左孩子及其子树),后输出根结点,最后输出右子树;后序遍历先找到并输出左子树,后找到并输出右子树,最后找全左右孩子及其子树后输出根结点。

另,以上查找孩子及其子树都基于其存在的前提下,注意另外判断,若存在,进行递归查找即可。

题目描述

有一个n( n <=10^6 )个结点的二叉树。给出每个结点的两个孩子结点的编号,建立一颗二叉树(根结点编号为1),求这棵树的深度。

输入描述

第一行一个整数n,表示n个结点。
接下来n行,第i行两个整数l和r,表示第i个结点的左孩子和右孩子的编号。

测试用例

测试⼀:
40 23 40 00 0
测试⼆:
22 00 0
测试三:
32 30 00 0
测试四:
72 30 45 60 00 07 00 0

代码实现

#include <iostream>
using namespace std;const int N = 1e6 + 10;int l[N],r[N];/*先序遍历*/
void dfsx(int u){cout << u << " ";if(l[u]) dfsx(l[u]);if(r[u]) dfsx(r[u]);
}/*中序遍历*/
void dfsz(int u){if(l[u]) dfsz(l[u]);cout << u << " ";if(r[u]) dfsz(r[u]);
}/*后序遍历*/
void dfsh(int u){if(l[u]) dfsh(l[u]);if(r[u]) dfsh(r[u]);cout << u << " ";  
}int main(){int n;cin >> n;for(int i = 1;i <= n;i++){cin >> l[i] >> r[i];}dfsx(1);cout << endl;dfsz(1);cout << endl;dfsh(1);cout << endl;return 0;
}

我们注意到,二叉树中不同于一般的树,没有存储父结点的信息,因此在遍历过程中,不需要另外数组进行标记是否访问过。

宽度优先遍历(BFS)

宽度优先遍历与常规树的宽度优先遍历相同,直接利用队列即可。

#include <iostream>
#include <queue>
using namespace std;const int N = 1e6 + 10;int l[N],r[N];void bfs(int u){queue<int> q;q.push(u);while(q.size()){int t = q.front();q.pop();cout << t << " ";if(l[t]) q.push(l[t]); if(r[t]) q.push(r[t]);}  
}int main(){int n;cin >> n;for(int i = 1;i <= n;i++){cin >> l[i] >> r[i];}bfs(1);cout << endl;return 0; 
}
http://www.dtcms.com/a/463367.html

相关文章:

  • 广东企业网站建设多少钱来宾网站建设公司
  • Thread构造函数详解
  • 南昌电商购物网站开发网站开发流程 图书
  • 什么做书籍的网站好网站 架构设计
  • 怎么做的英文网站私有云可以做网站
  • 化妆品公司网站模板wordpress屏蔽索引
  • 网站仿制教程做舞台灯光的在哪些网站接订单呢
  • Web 开发 25
  • 网站seo分析报告案例wordpress 手机更新
  • 成都软件定制宁波seo整站优化
  • 网站建立计划书南宁平台公司
  • 住建设部官方网站wordpress主题编辑
  • 网站需要什么服务器重庆市建设工程信息网劳务资质查询
  • 华为公司电子商务网站建设策划书网站建设 微信营销
  • 如何让搜索引擎不收录网站潮州东莞网站建设
  • 【OA办公系统】神点企业OA办公助手/全开源
  • 网站做支付宝花呗分期制作公司网站设计手绘
  • 10黄页网站建设四川在建项目信息查询
  • 广西建设工会网站个人游戏开发者 死路一条
  • 网站制作自己绍兴高端网站开发
  • 公司网站微信平台建设的好处山东建设执业资格注册中心网站
  • 网站后期维护内容搭建网站合同
  • 江西东乡网站建设wordpress中文语言
  • 推广app赚佣金平台有哪些南通优普网站建设优化
  • 建设一个网站需要那些技术医疗营销网站建设方案
  • 网站点击率如何做不要轻易注册一家公司
  • 重庆华鼎达网站建设连云港企业建站 网站
  • 张家港做网站的ai建筑设计平台
  • 做资源网站盈利点ps加dw做网站
  • 2014网站seo电商网站设计的企业