树的典型应用

二叉搜索树

静态查找:所查找集合的元素时不动的,在一个集合上主要做的便是find操作,而没有delete一个映射的操作

方法:二分查找,将要查找的数据事先的有序化

动态查找:所查找对象会发生变化,经常要发生插入,删除操作

书上的任意的一个结点他的值比左子树的值都要来的大,比右子树的值都要小,查找过程便成为了对当前结点的判断。

二叉搜索树(BST)—二叉排序树/二叉查找树

  • 一颗二叉树,可以为空,如果不为空需满足

    • 非空左子树的所有键值小于其根结点的键值
    • 非空右子树的所有键值大于其根结点的键值
    • 左,右子树都是二叉搜索树
操作函数
  • Position Find(elementtype x,bintree bst):从二叉搜索树BST中查找元素X,返回其所在结点的地址
  • Position Findmin(bintree bst):从二叉搜索树BST中查找并返回最小元素所在结点的地址
  • Position Findmax(bintree bst):从二叉搜索树BST中查找并返回最大元素所在结点的地址
  • bintree insert(elementtype x,bintree bst),插入
  • bintree delete(elementtype x,bintree bst),删除
查找操作
  • 查找从根结点开始,如果树为空,返回NULL;
  • 若搜索树非空,则根结点关键字和X进行比较,并进行不同处理
    • 若X小于根结点键值,只需在左子树中继续搜索
    • 若X大于根节点的键值,在右子树中进行继续搜索
    • 若两者比较结果是相等,搜索完成,返回指向此结点的指针
//尾递归
bintree find(ELementtype x, bintree bst)
{if (!bst)return NULL;//查找从根结点开始,如果树为空,返回NULL;if (x > bst->data){return find(x, bst->right);//若X大于根节点的键值,在右子树中进行继续搜索}if (x < bst->data){return find(x, bst->left);//若X小于根结点键值,只需在左子树中继续搜索}elsereturn bst;//若两者比较结果是相等,搜索完成,返回指向此结点的指针
}

由于非递归函数的执行效率高,可将尾递归函数改为迭代函数

//递归实现版
bintree iterfind(ELementtype x, bintree bst)
{while (bst){if (x > bst->data){bst=bst->right;//若X大于根节点的键值,在右子树中进行继续搜索}if (x < bst->data){bst = bst->left;//若X小于根结点键值,只需在左子树中继续搜索}elsereturn bst;//若两者比较结果是相等,搜索完成,返回指向此结点的指针}return NULL;//查找从根结点开始,如果树为空,返回NULL;
}

查找的效率决定于树的高度

查找最大和最小元素
  • 最大元素一定是在树的最右分支的端结点上
  • 最小元素一定是在树的最左分支的端结点上
//递归
bintree findmin(bintree bst)
{if (!bst)return NULL;else if (!bst->left)return bst;//一直查找有没有左节点,左结点如果没有代表就是最小结点所在的位置elsereturn findmin(bst->left);
}//循环
bintree findmax(bintree bst)
{if (bst){while (bst->right){bst = bst->right;}}return bst;
}
二叉搜索树插入

分析:关键是要找到元素应该插入的位置

bintree insert(ELementtype x, bintree bst)
{//若原树为空,生成并返回一个结点的二叉搜索树if (!bst){bst =(bintree)malloc(sizeof(struct treenode));bst->data = x;bst->left = bst->right = NULL;}else {//开始查找要插入元素的位置if (x < bst->data){bst->left = insert(x, bst->left);}else if (x > bst->data){bst->right = insert(x, bst->right);}//当找到了便将x赋给新建的空结点中}return bst;
}

二叉搜索树的删除

  • 要删除的是叶结点,直接删除,再修改其父结点指针,置为NULL
  • 要删除的结点只有一个孩子结点:将其父结点的指针指向要删除结点的孩子结点
  • 要删除的结点有左右两颗子树,用另一结点替代被删除结点,右子树的最小元素或则左子树的最大元素,原因,无论左子树的最小值或者右子树的最小值一定不会有两个结点
bintree deletetree(ELementtype x, bintree bst)
{bintree tmp;if (!bst){cout << "we can`t finf the num" << endl;}else if (x > bst->data){bst->right = deletetree(x, bst->right);//左子树递归删除}else if (x < bst->data){bst->left = deletetree(x, bst->left);//右子树递归删除}else{if (bst->left && bst->right)//左右两边都不空{tmp = findmin(bst->right);//找到右子树的最小值进行替代bst->data = tmp->data;bst->right = deletetree(bst->data, bst->right);}else{//被删除结点有一个或无子结点tmp = bst;if (!bst->left)//有右子树或无子结点{bst = bst->right;}else if (!bst->right)//有左子树或无子结点{bst = bst->right;}free(tmp);}}return bst;
}

平衡二叉树

搜索树结点的不同插入次序,会导致不同的深度平均查找长度ASL不同

左右两边结点数差不多,左右两边的高度差不多

  • 平衡因子(BF),BF(T)=hL-hR
  • hL,hR分别是T的左右子树的高度

平衡二叉树(AVL树)

任一结点的左右子树高度差的绝对值不超过1,即|BF(T)|<=1

高度为h的最小结点数=高度为h-1时最小结点数+高度为h-2时最小结点数+1

类似于斐波那契数列,nh=f(h+2)-1

给定结点数为n的AVL树的最大高度为O(log2(n))

平衡二叉树的调整

右旋

无论如何调整,都必须保证搜索树的框架能够成立

RR旋转,RR插入,右单旋

LL旋转,LL插入,左单旋

LR旋转,LR插入,左右旋转

RL旋转,RL插入

怎么判别:便是看插入结点把谁给破坏了

小白专场

题目:判断是否为同一颗二叉搜索树

给定一个插入序列可以唯一确定一颗二叉搜索树,然而一颗给定的二叉搜索树可以由多种不同的插入序列得到

对于输入的各种个插入序列,需要判断他们是否可以生成一样的二叉搜索树

求解思路
  • 分别建两颗搜索树的判别方法
  • 不建树的判别方法
  • 建一颗树,再判别其他序列是否与该树一致
    • 搜索树表示
    • 建搜索树T
    • 判别一序列是否与搜索树T一致
程序框架搭建
主函数
  • 读取N和L
  • 根据第一行序列建树T
  • 依据树T分别判别后面的L个序列是否能与T形成同一搜索树并输出结果
  • 主要建立两个函数,读入数据建立搜索树T,判别序列是否与T构成一样的搜索树
判别方法

如何判别序列与树t是否一致

方法:再树t中顺序搜索序列中的每个数

  • 若每次搜索所经过的结点再前面均出现过,则一致
  • 否则(某次搜索中遇到前面你未出现过的结点),则不一致
#include <stdio.h>
#include <stdlib.h>
#include<iostream>using namespace std;typedef struct Treenode* tree;//建立搜索树
struct Treenode
{int v;tree left, right;int flag;//用来判别一个序列是不是与树一致,作为结点有无被访问过的标记
};int main()
{int N,L,i;tree T;cin >> N;while (N){cin >> L;T = maketree(N);for (i = 0; i < L; i++){if (judge(T,N)){cout << "yes" << endl;}else{cout << "no" << endl;}resetT(T);//清除T中的标记flag}freetree(T);cin >> N;}return 0;}tree maketree(int n)
{tree t;int i, v;cin >> v;t = newnode(v);for (i = 1; i < n; i++){cin >> v;t = insert(t, v);}return t;
}tree newnode(int v)
{tree t = (tree)malloc(sizeof(struct Treenode));t->v = v;t->left = t->right = NULL;t->flag = 0;return t;
}tree insert(tree t, int v)
{if (!t)t = newnode(v);else {if (v > t->v){t->right = insert(t->right, v);}elset->left = insert(t->left, v);}return t;
}int check(tree t, int v)
{if (t->flag){if (v < t->v)return check(t->left, v);else if (v > t->v)return check(t->right, v);elsereturn 0;}else{if (v == t->v){t->flag = 1;return 1;}elsereturn 0;}
}//当发现序列中的某个数与T不一致时,必须把该序列后面的数全部都读完
int judge(tree t, int n)
{int i, v,flag = 0;//flag=0,代表目前还是一致的,1代表已经不一致了cin >> v;if (v != t->v)flag = 1;elset->flag = 1;for (i = 1; i < n; i++){cin >> v;if (!flag && !check(t, v))flag = 1;}if (flag)return 0;elsereturn 0;
}void resetT(tree t)//清除t中的每个结点的flag标记
{if (t->left)resetT(t->left);if (t->right)resetT(t->right);t->flag = 0;
}void freetree(tree t)//释放结点
{if (t->left)freetree(t->left);if (t->right)freetree(t->right);free(t);
}

二叉搜索树(BST)和平衡二叉树(AVL树)的概念与理解相关推荐

  1. 第七章 二叉搜索树 (d2)AVL树:插入

    转载于:https://www.cnblogs.com/ZHONGZHENHUA/p/10246808.html

  2. 真c++ 从二叉树到红黑树(3)之二叉搜索树BST

      此文章为从二叉树到红黑树系列文章的第三节,主要介绍介绍二叉搜索树BST,为AVL和RedBlack打下基础 文章目录 一.前面文章链接~(点击右边波浪线可以返回目录) 二.二叉搜索树BST的定义~ ...

  3. 五.树,二叉树,二叉搜索树(BST)和自平衡二叉搜索树(AVL)

    1.树 树是一种数据结构 比如:目录结构 树是一种可以递归定义的数据结构 树是由n个节点组成的集合: 如果 n=0, 那这是一颗空树 如果 n>0, 那存在1个节点作为树的根节点,其他节点可以分 ...

  4. 二叉搜索树BST红黑树

    二叉搜索树基础知识 提起红黑树咱们肯定要先说说这个二叉搜索树(BST) 二叉搜索树又叫二叉查找树,二叉排序树:它具有以下特点: 如果它的左子树不为空,则左子树上结点的值都小于根结点. 如果它的右子树不 ...

  5. 二叉搜索树BST的学习

    文章目录 二叉搜索树BST 什么是BST? 用BST做什么? 一.BST的特性 BST的特性是什么? 1.[230. 二叉搜索树中第K小的元素](https://leetcode.cn/problem ...

  6. 二叉搜索树(BST的理论剖析+代码实现)

    二叉搜索树(BST树) 文章目录 二叉搜索树(BST树) 1.二叉搜索树的概念 2.二叉搜索树的结构定义 2.1 二叉搜索树结点模板的定义 2.2 二叉搜索树类模板的定义 3.二叉搜索树的效率 4.二 ...

  7. 看动画学算法之:二叉搜索树BST

    文章目录 简介 BST的基本性质 BST的构建 BST的搜索 BST的插入 BST的删除 看动画学算法之:二叉搜索树BST 简介 树是类似于链表的数据结构,和链表的线性结构不同的是,树是具有层次结构的 ...

  8. 二叉搜索树 (BST)

    二叉搜索树 (BST : Binary Search Tree) 又名 二叉查找树 或 二叉排序树. 二叉搜索树: 左孩子的值 一定小于或等于 父结点的值 二叉搜索树: 右孩子的值 一定大于或等于 父 ...

  9. 二叉搜索树(BST)详解

    数据结构:二叉搜索树(BST) 今天咱们来聊聊二叉搜索树,先从字面上来理解,二叉,指的是有两个分支,左子树和右子树:搜索树,啥意思呢,搜索,是不是就是之前学过dfs和bfs那边学过,对啊,dfs就是深 ...

  10. 【数据结构与算法】3.二叉搜索树(BST)、c++代码

    二叉搜索树(BST).c++代码 参考 https://blog.csdn.net/c_living/article/details/81021510

最新文章

  1. 给django视图类添加装饰器
  2. 华为交换机SSH登录失败原因
  3. no module named sklearn
  4. Lesson 5.分类模型决策边界与模型评估指标
  5. Linq to sql 实现多条件的动态查询(方法一)
  6. DNS、IP地址、子网掩码和网关
  7. BeanUtils.copyProperties() 用法
  8. 苹果手机透明桌面_原来苹果手机辨别真假很容易!查看桌面1个图标,就能轻松分辨...
  9. 苹果cms V10模板 仿特视网自适应模板
  10. 基于highcharts+easui+java生成时趋图
  11. Linux服务器上安装node.js
  12. 拓端tecdat|使用Python和Keras进行主成分分析、神经网络构建图像重建
  13. y电容如何选型_到底什么是安规电容?有什么作用?一文彻底请明白
  14. 关闭微软拼音输入法自带的emoji表情包
  15. 微信抽奖小程序怎么做怎么弄?微信抽奖小程序制作方法详细介绍
  16. 编程不是一种知识,而是一门手艺。
  17. 利用python拼接图片代码_Python实现图片拼接的代码
  18. [转载]看我花式绕过校园网计费认证
  19. impala添加kerberos认证
  20. web页面:窗口切换

热门文章

  1. 微信公众平台开发之导入 jar 包
  2. 微服务大战:春季启动大战。 芭蕾舞女演员
  3. 【笔记整理】软考-软件设计师
  4. 通过Python的pyttsx3库将文字转为音频
  5. Android系统_MTK_android11_集成openssh
  6. 【经验分享】关于RT-Thread studio gitee源下载软件包失败以及git拉取Gitee仓库报错
  7. 【C++】C++ 中的 IO 流
  8. blog开通,幸甚! ^_^
  9. 大气科学计算机,这所高校大气科学学科世界一流,被誉为“气象人才的摇篮”...
  10. 华为用一己之力,撬动了整个未来!