what's the 二叉树
what's the 树
在了解二叉树之前,首先我们得有树的概念。
树是一种数据结构又可称为树状图,如文档的目录、HTML的文档树都是树结构,它是由n(n>=1)个有限节点组成一个具有层次关系的集合。把它叫做“树”是因为它看起来像一棵倒挂的树,也就是说它是根朝上,而叶朝下的。它具有以下的特点:
- 每个节点有零个或多个子节点;
- 没有父节点的节点称为根节点;
- 每一个非根节点有且只有一个父节点;
- 除了根节点外,每个子节点可以分为多个不相交的子树;
有关树的一些相关术语:
- 节点的度:一个节点含有的子树的个数称为该节点的度;
- 叶节点或终端节点:度为0的节点称为叶节点;
- 非终端节点或分支节点:度不为0的节点;
- 双亲节点或父节点:若一个节点含有子节点,则这个节点称为其子节点的父节点;
- 孩子节点或子节点:一个节点含有的子树的根节点称为该节点的子节点;
- 兄弟节点:具有相同父节点的节点互称为兄弟节点;
- 树的度:一棵树中,最大的节点的度称为树的度;
- 节点的层次:从根开始定义起,根为第1层,根的子节点为第2层,以此类推;
- 树的高度或深度:树中节点的最大层次;
- 堂兄弟节点:双亲在同一层的节点互为堂兄弟;
- 节点的祖先:从根到该节点所经分支上的所有节点;
- 森林:由m(m>=0)棵互不相交的树的集合称为森林;
树的种类有:无序树、有序树、二叉树、霍夫曼树。其中最重要应用最多的就是二叉树,下面我们来学习有关二叉树的知识。
二叉树
二叉树的定义为度不超过2的树,即每个节点最多有两个叉(两个分支)。上面那个例图其实就是一颗二叉树。
二叉树有两个特殊的形态:满二叉树和完全二叉树
满二叉树
一个二叉树,如果除了叶子节点外每一个层的结点数都达到最大值,则这个二叉树就是满二叉树。
完全二叉树
叶节点只能出现在最下层和次下层,并且最下面一层的结点都集中在该层最左边的若干位置的二叉树为完全二叉树。即右边的最下层和次下层可以适当缺一个右子数
完全二叉树是效率很高的数据结构
二叉树的遍历
二叉树的链式存储:将二叉树的节点定义为一个对象,节点之间通过类似链表的链接方式来连接。
二叉树结点的定义
#二叉树结点的定义
class BiTreeNode:
def __init__(self, data):
self.data = data
self.lchild = None
self.rchild = None
二叉树的遍历分为四种——前序遍历、中序遍历、后序遍历和层级遍历
设树结构为:
- 前序遍历:先打印根,再递归其左子树,后递归其右子数 E ACBD GF
- 中序遍历:以根为中心,左边打印左子树,右边打印右子树(注意,每个子树也有相应的根和子树) A BCD E GF
- 后序遍历:先递归左子树,再递归右子树,后打印根(注意,每个子树也有相应的根和子树BDC A FG E
- 层次遍历:从根开始一层一层来,同一层的从左到右输出E AG CF BD
四种遍历方法的代码实现:
from collections import deque
#结点的定义
class BiTreeNode:
def __init__(self, data):
self.data = data
self.lchild = None
self.rchild = None
#二叉树结点
a = BiTreeNode('A')
b = BiTreeNode('B')
c = BiTreeNode('C')
d = BiTreeNode('D')
e = BiTreeNode('E')
f = BiTreeNode('F')
g = BiTreeNode('G')
#结点之间的关系
e.lchild = a
e.rchild = g
a.rchild = c
c.lchild = b
c.rchild = d
g.rchild = f root = e #前序遍历:先打印根,再递归左孩子,后递归右孩子
def pre_order(root):
if root:
print(root.data, end='')
pre_order(root.lchild)
pre_order(root.rchild)
#中序遍历:以根为中心,左边打印左子树,右边打印右子树(注意,每个子树也有相应的根和子树)
#(ACBD) E (GF)-->(A(CBD)) E (GF)-->(A (B C D)) E (G F)
def in_order(root):
if root:
in_order(root.lchild)
print(root.data, end='')
in_order(root.rchild) #后序遍历:先递归左子树,再递归右子数,后打印根(注意,每个子树也有相应的根和子树)
# (ABCD)(GF)E-->((BCD)A)(GF)E-->(BDCA)(FG)E
def post_order(root):
if root:
post_order(root.lchild)
post_order(root.rchild)
print(root.data, end='') #层次遍历:一层一层来,同一层的从左到右输出
def level_order(root):
queue = deque()
queue.append(root)
while len(queue) > 0:
node = queue.popleft()
print(node.data,end='')
if node.lchild:
queue.append(node.lchild)
if node.rchild:
queue.append(node.rchild) pre_order(root)#EACBDGF
print("")
in_order(root)#ABCDEGF
print("")
post_order(root)#BDCAFGE
print("")
level_order(root)#EAGCFBD
前序遍历、中序遍历、后序遍历、层级遍历代码实现
二叉搜索树
二叉搜索树(Binary Search Tree),它或者是一棵空树,或者是具有下列性质的二叉树: 若它的左子树不空,则左子树上所有结点的值均小于它的根结点的值; 若它的右子树不空,则右子树上所有结点的值均大于它的根结点的值; 它的左、右子树也分别为二叉搜索树。
二叉搜索树一个很好玩的网址,集成了增删改的功能:https://visualgo.net/en/bst
二叉搜索树的中序遍历得到的是原来列表按升序排序的列表
由列表生成二叉搜索树、通过二叉搜索树查询值和删除值的示例代码:
#结点定义
class BiTreeNode:
def __init__(self, data):
self.data = data
self.lchild = None
self.rchild = None
#建立二叉搜索树(循环列表,插入值)
class BST:
def __init__(self, li=None):
self.root = None
if li:
self.root = self.insert(self.root, li[0])#列表的第一个元素是根
for val in li[1:]:
self.insert(self.root, val)
#生成二叉搜索树递归版本
def insert(self, root, val):
if root is None:
root = BiTreeNode(val)
elif val < root.data:#插入的值小于root,要放到左子树中(递归查询插入的位置)
root.lchild = self.insert(root.lchild, val)
else:#插入的值大于root,要放到右子树中(递归查询插入的位置)
root.rchild = self.insert(root.rchild, val)
return root
#生成二叉搜索树不递归的版本
def insert_no_rec(self, val):
p = self.root
if not p:
self.root = BiTreeNode(val)
return
while True:
if val < p.data:
if p.lchild:
p = p.lchild
else:
p.lchild = BiTreeNode(val)
break
else:
if p.rchild:
p = p.rchild
else:
p.rchild = BiTreeNode(val)
break
#查询递归版本
def query(self, root, val):
if not root:
return False
if root.data == val:
return True
elif root.data > val:
return self.query(root.lchild, val)
else:
return self.query(root.rchild, val)
#查询非递归版本
def query_no_rec(self, val):
p = self.root
while p:
if p.data == val:
return True
elif p.data > val:
p = p.lchild
else:
p = p.rchild
return False #中序遍历,得到的是升序的列表
def in_order(self, root):
if root:
self.in_order(root.lchild)
print(root.data, end=',')
self.in_order(root.rchild) tree = BST()
for i in [1,5,9,8,7,6,4,3,2]:
tree.insert_no_rec(i)
tree.in_order(tree.root)
#print(tree.query_no_rec(12))
列表生成二叉搜索树、二叉搜索树查询值和删除值的方法
二叉搜索树的应用——AVL树、B树、B+树
AVL树
AVL树:AVL树是一棵自平衡的二叉搜索树。
AVL树具有以下性质: 根的左右子树的高度之差的绝对值不能超过1 根的左右子树都是平衡二叉树
AVL的实现方式:旋转
B树
B树是一棵自平衡的多路搜索树。常用于数据库的索引。
在B-树中查找给定关键字的方法是,首先把根结点取来,在根结点所包含的关键字K1,…,Kn查找给定的关键字(可用顺序查找或二分查找法),若找到等于给定值的关键字,则查找成功;否则,一定可以确定要查找的关键字在Ki与Ki+1之间,Pi为指向子树根节点的指针,此时取指针Pi所指的结点继续查找,直至找到,或指针Pi为空时查找失败。
B+ 树
B+树的查找
1
2
3
4
5
6
7
8
9
10
|
Function: search (k) return tree_search (k, root); Function: tree_search (k, node) if node is a leaf then return node; switch k do case k < k_0 return tree_search(k, p_0); case k_i ≤ k < k_{i+ 1 } return tree_search(k, p_{i+ 1 }); case k_d ≤ k return tree_search(k, p_{d+ 1 }); //伪代码假设没有重复值 |
B+树的插入
B+树的删除
what's the 二叉树的更多相关文章
- [数据结构]——二叉树(Binary Tree)、二叉搜索树(Binary Search Tree)及其衍生算法
二叉树(Binary Tree)是最简单的树形数据结构,然而却十分精妙.其衍生出各种算法,以致于占据了数据结构的半壁江山.STL中大名顶顶的关联容器--集合(set).映射(map)便是使用二叉树实现 ...
- 二叉树的递归实现(java)
这里演示的二叉树为3层. 递归实现,先构造出一个root节点,先判断左子节点是否为空,为空则构造左子节点,否则进入下一步判断右子节点是否为空,为空则构造右子节点. 利用层数控制迭代次数. 依次递归第二 ...
- c 二叉树的使用
简单的通过一个寻找嫌疑人的小程序 来演示二叉树的使用 #include <stdio.h> #include <stdlib.h> #include <string.h& ...
- Java 二叉树遍历右视图-LeetCode199
题目如下: 题目给出的例子不太好,容易让人误解成不断顺着右节点访问就好了,但是题目意思并不是这样. 换成通俗的意思:按层遍历二叉树,输出每层的最右端结点. 这就明白时一道二叉树层序遍历的问题,用一个队 ...
- 数据结构:二叉树 基于list实现(python版)
基于python的list实现二叉树 #!/usr/bin/env python # -*- coding:utf-8 -*- class BinTreeValueError(ValueError): ...
- [LeetCode] Path Sum III 二叉树的路径和之三
You are given a binary tree in which each node contains an integer value. Find the number of paths t ...
- [LeetCode] Find Leaves of Binary Tree 找二叉树的叶节点
Given a binary tree, find all leaves and then remove those leaves. Then repeat the previous steps un ...
- [LeetCode] Verify Preorder Serialization of a Binary Tree 验证二叉树的先序序列化
One way to serialize a binary tree is to use pre-oder traversal. When we encounter a non-null node, ...
- [LeetCode] Binary Tree Vertical Order Traversal 二叉树的竖直遍历
Given a binary tree, return the vertical order traversal of its nodes' values. (ie, from top to bott ...
- [LeetCode] Binary Tree Longest Consecutive Sequence 二叉树最长连续序列
Given a binary tree, find the length of the longest consecutive sequence path. The path refers to an ...
随机推荐
- duilib进阶教程 -- TreeView控件(6)
代码下载:http://download.csdn.net/detail/qq316293804/6483905 上一个教程中,界面已经和迅雷一模一样啦,大小和位置一个像素都不差哟,亏得Alberl调 ...
- 8 -- 深入使用Spring -- 6...1 Spring支持的事务策略
8.6.1 Spring支持的事务策略 JTA.JDBC.Hibernate Java EE应用的传统事务有两种策略:全局事务和局部事务.全局事务由应用服务器管理,需要底层服务器的JTA(Java T ...
- offsetHeight,clientHeight,scrollHeight,offsetY等属性的理解
el.offsetHeight = height + padding + border(滚动条是在边框内的,自然也包括在内) el.clientHeight = 可视化看到的高度 (就是content ...
- 隐藏响应的server,X-Powered-By
隐藏X-Powered-By 修改 php.ini 文件 设置 expose_php = Off apache 隐藏 server 修改httpd.conf 设置 ServerSignature Of ...
- 【Vue】---编写Vue插件流程---【巷子】
一.在Vue中编写插件流程 1.创建组件 components/message.vue <template> <div class="message" v-if= ...
- centos linux7的一些操作
进入centos7的一些界面后,按ctrl+alt+F2,则可进入全shell界面,不过要登录root的密码: 从全shell转为gnome 界面窗口,按alt+F1: *************** ...
- 在 .NET Framework Data Provider for Microsoft SQL Server Compact 3.5 中发生错误
32位机器删除 HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\VisualStudio\version\DataProviders\{7C602B5B-ACCB-4acd ...
- F#周报2019年第1期
新闻 介绍versionsof.net InfoQ正在寻找F#社区的声音 使用F#开发端对端的实际应用 UnoPlatform上的F# Elmish 视频及幻灯片 事件溯源DIY02--事件,事件存储 ...
- cadence xbl封装转AD
下载一个 软件 免费试用 导出到ad,出现一个脚本,脚本工程直接拉到ad里面,然后 有这两个文件,启动是有顺序的,顺序一旦错误就会产生大问题,没有任何反应 设置工程启动顺序,再次启动,出现打开文件窗口 ...
- 闭区间套定理(Nested intervals theorem)讲解2
①确界与极限,看完这篇你才能明白 http://www.cnblogs.com/iMath/p/6265001.html ②这个批注由这个问题而来 表示$c$可能在$\bigcap_{n=1}^{\i ...