平衡二叉树总结一:二叉搜索树

原创 2017年01月03日 10:20:38

  这段时间一直再刷leetcode,现在刷了快一半了吧,感觉没什么状态了,再继续刷可能就不太好了,想想不如回头再补补算法吧。总结了自己在基础算法上的一些短板,准备后面这些时间把它们都补上。好了,上正题。

  平衡二叉树算是应用最广泛的树型结构了吧,至少在内存里面是吧。刚开始学数据结构的时候,树的那一章基本没怎么看,大部分精力都放在了排序和图论里,而且感觉树也挺简单的,现在刷题才慢慢发现这种数据结构的威力,虽然c++的算法库已经有了现成的工具,但是学习好这种数据结构的思想还是很有必要的。

  首先,平衡二叉树是一颗二叉搜索树。其结构满足 root->left->val < root-> val < root->right->val 即根节点左儿子值 < 根节点值 < 右儿子值,并且根节点左右儿子也是二叉搜索树。

第一次作图,凑或着看吧

struct searchTree{
  searchTree* left;
  searchTree* right;
  int val;
}
typedef serachTree* tree;
二叉搜索树的结构,c++版。主要是一个左指针、一个右指针、一个值,不难看出left与right其实是“多余”的,然而没有这俩多余的域二叉树的搜索效率就无从谈起,这就是空间
换时间的典型吧。


  1.二叉搜索树的搜索

  二叉搜索树操作都很简单,搜索时,我们只需比较待搜索值与根节点的大小,比根节点大肯定在左子树,这样我们排除了右子树上节点,这就是二叉搜索树能节省时间的原理,当然比根节点小自然就在右边,相等的话该节点就是我们要找的节点了,代码如下:

/*递归的写法,当然也可以改成循环的,不过递归的逻辑更简明。*/
tree search(tree t,int& val){
  if(t==NULL)return NULL;//为空说明没找到该值。
  if(val>t->val) return search(t->right,val);//大于根节点,往右走。
  else if(val<t->val) return search(t->left,val);//小于往左走。
  return t;//等于,返回该节点。
}
2.插入

/*二叉树的插入,与搜索算法类似。比根节点大就往右插,小往左(等于的情形需要特别
处理,这里先不说,之后的也不考虑等于的情形),直到遇到空节点。*/
tree insert(tree t,int& val){
  if(t==NULL){
    t = new searchTree;
    t->val = val;
    t->left = t->right = NULL;
  }
  if(val>t->val)t->right = insert(t->right,val);
  if(val<t->val)t->left = insert(t->left,val);
  return t;
  //其实返回t不是最优的写法,会多一个赋值过程,不过这样程序看起来更简明。
}
3.删除

  相对而言,删除操作是比较复杂的,需要寻找删除节点的左子树的最大值,或右子树最小值来代替该节点,中间会有一些细节需要注意。

代码稍长,主要是最后寻找替代节点比较麻烦。

/*二叉树的删除或多或少会有些复杂,如果要删除的叶节点,直接删除即可。但是倘若
要删除非叶节点则需要找一个节来替代它。一般是选取左子树的最大值或右子树的最小值。*/
tree del(tree t,int& val){
  if(t==NULL)return NULL;
  if(val>t->val)t->right=del(t->right,val);//递归删除左边
  if(val<t->val)t->left = del(t->left,val);//递归删除右边
  if(val==t->val){//找到节点
    tree v,p=t;
    if(t->left){//如果该节点有左子树,找到左子树最大值。
      for(v=t->left;v->right;p=v,v=v->right){}
      t->val = v->val;//最大值替换删除值。
      if(p==t)p->left = v->left;//如果p节点等于t说明左子树最大值正好为t的左儿子。
      //v自然没有了右儿子,所以将v左儿子赋值给p的右儿子。
      else{p->right = v->left;}//此时p改变过一次,需要p的右儿子是v,所以需要改变一下。
      delete v;//删除v。
    }
    else if(t->right){
      for(v=t->right;v->left;p=v,v=v->left){}
      t->val = v->val;
      if(p==t)p->right = v->right;
      else{p->left = v->right;}
      delete v;
    }
    else{
      delete t;
      return NULL;
    }
    return t;
  }
}

4.总结

  二叉搜索树的搜索与插入效率理想的情形下(左右子树都填满)自然是log2(n)的,但是实际操作中往往达不到这个要求,比如插入的序列是递增的,此时该树退化成

链表,效率变为o(n)。所以为了防止该情况的出现,人们开发出了二叉平衡树,也就是对于根节点而言其左右子树尽量相等的二叉搜索树,平衡条件不同,树的搜索与插入

效率不同。不过一般平衡条件越严格,搜索效率越高,但是插入就变得困难了。

  二叉平衡树有很多,如最早的avl树以及其变种红黑树,无需额外空间的splay树,编程简单的treap树,SBT树,替罪羊树等,待我一一总结起来。

 

相关文章推荐

关于树的总结从二叉树->二叉搜索树->平衡二叉树->红黑树->B树与B+树

二叉树的定义与性质,包括各种操作的源代码在本博客的的此处:二叉树 二叉搜索树(Binary Search Tree)的定义性质以及源码实现在本博客此处:二叉搜索树 平衡二叉树(AVL树),是一棵完全二...

数据结构中常见的树(二叉搜索树、AVL平衡二叉树、RBT红黑树、B-树、B+树、B*树)

BST树        即二叉搜索树:        1.所有非叶子结点至多拥有两个儿子(Left和Right);        2.所有结点存储一个关键字;        3...

数据结构中常见的树(BST二叉搜索树、AVL平衡二叉树、RBT红黑树、B-树、B+树、B*树)

数据结构中常见的树(BST二叉搜索树、AVL平衡二叉树、RBT红黑树、B-树、B+树、B*树) 分类: 数据结构2014-09-16 12:07 1181人阅读 评论(0) 收藏 举报 ...

数据结构 学习笔记(五):树(中):二叉搜索树,平衡二叉树

请跟着上一讲 数据结构 学习笔记(四):树(上):树的表示,二分查找,二叉树,先中后层次遍历 继续学习4.1 二叉搜索树4.1.1 二叉搜索树及查找什么是二叉搜索树回顾上一讲提到的查找问题: 静态查找...
  • Jurbo
  • Jurbo
  • 2017年07月09日 15:26
  • 456

数据结构中常见的树(BST二叉搜索树、AVL平衡二叉树、RBT红黑树、B-树、B+树、B*树)

BST树        即二叉搜索树:        1.所有非叶子结点至多拥有两个儿子(Left和Right);        2.所有结点存储一个关键字;        3...

《剑指offer》之二叉搜索树(BST)与平衡二叉树(AVL树)专题

《剑指offer》之二叉搜索树(BST)与平衡二叉树(AVL树)专题

【数据结构】树(二):二叉树&二叉搜索树&平衡二叉树(C++实现)

二叉树/二叉搜索树/平衡二叉树

【数据结构】树与树的表示、二叉树存储结构及其遍历、二叉搜索树、平衡二叉树、堆、哈夫曼树与哈夫曼编码、集合及其运算

1、树与树的表示 什么是树? 客观世界中许多事物存在层次关系 人类社会家谱 社会组织结构 图书信息管理 分层次组织在管理上具有更高的效率! 数据管理的基...

平衡二叉树、完全二叉树、满二叉树、二叉搜索(查找 / 排序)树、平衡二叉搜索树、二叉堆

查了一些博客、百科整理出以下关于树的定义以及易混点: 平衡二叉树:一棵空树或左右两个子树的高度差的绝对值不超过1,并且左右两个子树都是平衡二叉树。(注意:实际应用中很少有不是二叉搜索树的平衡二叉树...

基于C写的平衡二叉树

  • 2016年03月24日 16:18
  • 3KB
  • 下载
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:平衡二叉树总结一:二叉搜索树
举报原因:
原因补充:

(最多只允许输入30个字)