数据结构系列-11 二叉搜索数(bst)

本文参考 跟波波学数据结构视频

 

1.什么是树?

  • 树是一个无环的,无向连同图
  • 有n个节点,和n-1条边
  • 有一个根节点,通常需要一个引用
  • 任意点条连接,且只有条路径

2.树的相关概念

  • 父节点:直接相连的两个节点,上面的叫父节点。
  • 子节点:下面的叫子节点。
  • 根节点:没有父节点,有的实现中,根节点的父节点,指向自己。
  • 叶子节点:没有子节点的节点。
  • 子树:包含再一棵树中的小数 用\Delta表示

3.什么是二叉树(bt)

英文 binnary tree 简称BT ,每个节点最多只有两颗数,

4.什么是二叉搜索数

二叉搜索数 ,英文 binnary search tree 简称BST,二叉搜索树,是二叉树且满足BST不变式,对于任意有子树的节点都满足,左子树的值都小于节点的值,右子树的值都大于节点的值。

5.二叉搜索树的用途

  • 实现 map或者set这样的抽象数据结构。
  • 实现红黑树
  • 实现平衡二叉搜索树
  • 伸展树 。。。
  • 实现堆~二叉堆
  • 构建语法树
  • 树堆(treap)~ 一种概率数据结构

6.BST的操作和复杂度

BST复杂度
操作平均情况最坏情况
插入insertO(logn)O(n)
删除deleteO(logn)O(n)
移除removeO(logn)O(n)
搜索searchO(logn)O(n)

 7.动画演示

 (1)添加元素,跟波波学数据结构_插入

 (2)移除元素,跟波波学数据结构_搜索和删除

8.二叉树的遍历(先序遍历、中序遍历、后续遍历、层遍历)

(1)伪代码

//先序遍历
preorder(node):
    if node == null: return 
    print(node.value)      //先序遍历再递归前打印输出
    preorder(node.left)
    preorder(node.right)

//中序遍历
inorder(node):  
    inorder(node.left)
    if node == null: return
    print(node.value)  //中序遍历再递归中间打印输出
    inorder(node.right)

//中序遍历
postorder(node):  
    inoder(node.left)
    inoder(node.right)
    if node == null: return
    print(node.value)  //后序遍历再递归后打印输出

/**非递归方式实现 **/
//先序遍历
Let Q be Queue
Q.enqueue(rootNode)
while Q is not empty:
    node = Q.dequeue()
    node.visited = true
    if node.right is not null:
        Q.enqueue(node.right)
    if node.left is not null:
        Q.enqueue(node.left)
// 中序遍历
Let Q be Queue
Q.enqueue(rootNode)
while Q is not emtpy:
    trav = Q.top() //如果栈没有top()操作 需要每次入栈时记录,把入栈元素赋值给变量trav
    if trav.left is not null:
        Q.enqueue(trav.left)
    else:
        node = Q.dequeue()
        node.visited = true
        if node.right is not null:
            Q.enqueue(node.right)

//后续遍历
Let Q1 be a Queue
Let Q2 be a Queue
Q1.enqueue(rootNode)
while Q1 is not null:
    node = Q1.dequeue()
    Q2.enqueue(node)
    if node.left is not null:
        Q1.enqueue(node.left)
    if node.right is not null:
        Q1.enqueue(node.right)
while Q2 is not null:
    node = Q2.dequeue()
    node.visited









(2)二叉树,经过三种遍历后,会得到三个线性的串。

(3)已知中序遍历和另外一个可以求第三个。也可以反推树的结构。

下面我们模拟根据前序遍历和中序遍历构建二叉树的过程:

我们已经知道:前序遍历按照先访问根,再访问子节点的顺序进行遍历;中序遍历则按照先访问左子树,再访问根,再访问右子树的顺序进行遍历,那么我们可以确定一个恢复树结构的思路:

  1. 首先根据先序遍历开头确定根节点A:第一个节点一定是根节点
  2. 根据中序遍历的性质,从A进行分割,将整棵二叉树划分为左子树和右子树,左子树中序遍历BCDE;右子树中序遍历GHFI
  3. 根据左子树下后序遍历分割先序遍历,左子树先序遍历BCDE;右子树先序遍历FGHI
  4. 重复做前面的过程,根据先序遍历确定当前层的根节点,再分割树,直至中序遍历只剩一个节点为止停止递归

 摘抄自:二叉树的遍历及根据遍历反推树的方法详解_HeartFireY的博客-CSDN博客

(4)二叉搜索树的中序遍历,元素是按照从小到大顺序输出的。

(5)层次遍历,使用宽度优先搜索(DFS)

为了实现宽度优先搜索(BFS),我们需要维护一个queue,其中记录剩下的需要遍历的节点。

队列重点节点先从根节点开始,一直队列为空。

伪代码如下:

let Q be a Queue
Q.EnQueue(root_node)
while Q is not empty :
   current := queue.Dequeue()
   current.visited
   if current has child :
       for child in current.children:
            Q.EnQueue(child)
  
   

遍历过程可参考 跟波波学数据结构_树的遍历 9分钟处

参考:跟波波学数据结构_树的遍历

9.二叉搜索树的go语言实现。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值