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 ...
随机推荐
- [hive] hive 安装、配置
一.hive安装 1.官网下载 1.2.2版本 http://apache.fayea.com/hive/hive-1.2.2/ 2. 解压,此处目录为 /opt/hadoop/hive-1.2.2 ...
- 使用WPF Animated GIF实现GIF图片的播放
这个类库很方便,也很简单:http://wpfanimatedgif.codeplex.com/ 参考博客:http://blog.csdn.net/gqqnb/article/details/721 ...
- Xamarin Mono Android实现“再按一次退出程序”
开始研究Android平台软件编程,Xamarin Mono for Android上手快,跨平台共享代码,代价是bug多多,是一味可口的毒药啊! 环境VS2012 + Xamarin Mono An ...
- 终端IO(上)
一.综述 终端IO有两种不同的工作方式: 规范方式输入处理.在这种方式中,终端输入以行为单位进行处理.对于每个读要求,终端驱动程序最多返回一行. 非规范方式输入处理.输入字符不以行为单位进行装配 如果 ...
- 腾讯云极速配置NodeJS+LNMP运行环境
版权声明:本文由吴逸翔原创文章,转载请注明出处: 文章原文链接:https://www.qcloud.com/community/article/848754001487150669 来源:腾云阁 h ...
- lsass 病毒手动清除方法
病毒症状进程里面有2个lsass.exe进程,一个是system的,一个是当前用户名的(该进程为病毒).双击D:盘打不开,只能通过右击选择打开来打开.用kaspersky扫描可以扫描出来,并且可以杀掉 ...
- jenkins之 pipeline 小尝试
最近,一个小需求,动态建立slave节点来执行自动化用例,原有jenkins 老方式不满足需求,就用到jenkins2的pipeline来实现,但在实现过程中,2个小坑记录下 1.jenkins不能读 ...
- day_5.28 py网络编程
端口 socket简介: socket为一个类 s接收的是返回的对象引用 2018-5-28 15:52:47 开始进行网络编程 udp 套接字 encode() 编码 decode() 解码 ' ...
- LogisticRegression 和 LogisticRegressionCV
在scikit-learn中,与逻辑回归有关的主要是这3个类.LogisticRegression, LogisticRegressionCV 和logistic_regression_path.其中 ...
- 【react】---context的基本使用新版---【巷子】
一.全局定义context对象 globalContext.js import React from "react"; const GlobalContext = React.cr ...