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 ...
随机推荐
- [JS] ECMAScript 6 - Array : compare with c#
扩展运算符(spread) 先复习下 rest 参数. (1) argument模式,但不够好. // https://blog.csdn.net/weixin_39723544/article/de ...
- 十三、K3 WISE 开发插件《SQL语句WHERE查询-范围查询/模糊查询》
0.存储过程开头变量定义 ), --单据起始日期 ), --单据截止日期. ), ), ), ), ) @FType varchar(50), --单据类型@FBillNo varchar(50), ...
- play mp3 in c#
using System; using System.Runtime.InteropServices; using System.Text; using System.IO; using System ...
- Mac下git通过SSH进行免密码安全连接github
Git——The stupid content tracker(傻瓜内容跟踪器) Git是Linux的缔造者Linus Torvalds为了帮助管理Linux内核源码而开发的一款免费.开源的分布式版本 ...
- 5.STM32通用定时器TIM3中断
1.通用定时器TIM3中断 #include "timer.h" #include "led.h" void TIM3_Int_Init(u16 arr,u16 ...
- RPM二进制包软件安装
通过rpm –qa查找已安装的软件包 如果想精确查找某一软件,可以通过管道命令grep来实现 精确查找rpm –qa |grep关键词 如 rpm –qa |grep vim 卸载已安装rpm包 ...
- python如何去掉字符串‘\xa0’
发现问题: 最近在用爬虫爬取网页信息时,在网页源码中遇到了“ "字符串,经查阅,发现该字符是不间断空格符.我们通常所用的空格是 \x20 ,是在标准ASCII可见字符 0x2 ...
- base标签浏览器兼容问题
<% String path = request.getContextPath(); String basePath = request.getScheme() + "://" ...
- sqlServer自动代码提示功能
第一种方法: 首先确认 自己的sqlServer2008自身的提示功能有没有被屏蔽了! 打开sqlserver2008 -- 工具 -- 选项 -- 文本编辑器 -- 所有语言 -- 勾选 语句结束 ...
- sql里的ROW_NUMBER() OVER是啥意思?
是一个分析函数,生成一个排序列select row_number(XX) over(partition by XXX order by XX [desc/asc]) frou table;partit ...