其他分享
首页 > 其他分享> > 2021-10-10

2021-10-10

作者:互联网

这个周做了一些题并学习了二叉树,就总结一下二叉树的知识吧。
一、二叉树
1.二叉树每个结点最多有两个子节点,分别是左孩子和右孩子,二叉树存在满二叉树和完全二叉树等情况。
2.遍历二叉树需要用到搜索的知识,用深度优先遍历相对较为简便。
3.二叉树有着先序遍历、中序遍历、后序遍历等情况。先序遍历按照父节点、左儿子、右二子的顺序进行组合。中序遍历按照左儿子、父节点、右儿子的顺序进行组合,而后续遍历的顺序则是左儿子、右儿子、父节点。一颗树当已知两种以上的排序方法则能求出整个树(先序+后序属于特殊情况,不能写出)
4.书上的例题:hdu1710
已知先序和中序排列,输出后续排列。书上的代码除了输出外还同时拥有检验先序和中序的代码。其实这题的重点就在建树和输出后序排列这两点上。
(1)建树:

先序:1 2 4 7 3 5 8 9 6
中序:4 7 2 1 8 5 9 3 6

这道题已知是先序和中序排列,从先序找到第一个数字1,这个点是根节点,然后找到它在中序中的位置。(因为中序排列是先左儿子然后才是节点)因此可知1左面的三个节点都位于根节点的左面,剩下五个自然分布在右边。用相同的原理去调查先序排列第二个数2,得知4 7是2的左儿子。但它没有右儿子。由此调查所有先序结点直到画出整棵树

void tree(int l,int r,int &t,node *root)  //  建树
{  int flag=-1;   
   for(int i=l;i<=r;i++)
   if(in[i]==pre[t]){
      flag=i;break;   // 对先序排列的每个结点依次使用上述方法
      }
      if(flag==-1) return;  //  如果建完树就结束函数
      root=new node(in[flag]);
      t++; //  调查结点右移
      if(flag>l)  tree(l,flag-1,t,root->l);  // 递归,将满足条件的数放到左子树上
      if(flag<r)  tree(flag+1,r,t,root->r);

(2)排序:
已知一颗二叉树可以输出其先序、中序、后序遍历:

void xianxu(node *root){
  if(root!=NULL){   int k=0;
         paixu[k++]=root->value;   //输出结点上的数字
         xianxu(root->l);  // 深度优先搜索
         xianxu(root->r);
         }
}
void zhongxu(node *root){  // 左儿子,父节点,右儿子
          if(root!=NULL)
          {
          zhongxu(root->l);   // 先递归到左子树的底层
          paixu[k++]=root->value;
          zhongxu(root->r);
          }
}
void houxu(node *root){   // 左儿子,右儿子,父节点
      if(root!=NULL){
      houxu(root->l);
      houxu(root->r);
      paixu[k++]=root->value;
      }
}

二、二叉搜索树
1.每个元素有唯一的键值,就像结点上的数字。
2.对于二叉搜索树来说,结点的键值比它的左子树的所有结点大,比它的右子树所有结点小 。
3.二叉搜索树用中序遍历就可以得到它的有效排列,结点的键值就是按照中序排列来建树的。
4.STL中的set和map就是用二叉搜索树实现的。

三、Treap树
1.Treap树是树和堆的结合,树指的是二叉搜索树,除此之外还给每个结点添加了一个优先级的权值,在这棵树上,根结点的优先级最大。
2.在二叉搜索树里建树可能会退化为链表,将每个结点的优先级随机赋值,那么生成的Treap树也是随机的。
3.随机赋值可以在一定程度上避免树退化为链表,但是它有可能并不满足堆的性质,因此在建树时需要同时做出一定的调整,即Treap树的左旋和右旋。
4.随机分配优先级后,如果结点的优先级比父节点的高,则让结点往上走,替代父节点。

void xuanzhuan(Node *o,int d){  // d=0左旋,d=1右旋
      Node *k=o->son[1-d];    
      o->son[1-d]=k->son[d];   
      k->son[d]=o;    
      o=k;    //  根结点替换
      }

四、Splay树(这个看的时间不长,以后还会专门研究一下)
1.Splay同样是一种二叉搜索树,它可以把某个结点上旋到根结点的位置(任意结点旋转到根)。
2.Splay树的分裂和合并十分简便,Treap树的分裂和合并就十分繁琐。
3.Splay树的旋转情况有很多,网上很多博客有六七种旋转情况,书上就只有三种。
(1)父结点就是根
x的父节点就是根,只需要旋转一次。
(2)父结点不是根,x、x的父结点、x的父结点的父节点三点共线。此时先做两次单旋,先旋转x的父节点,然后再旋转x。
(3)x、x的父节点、x的父节点的父节点三点不共线,把x按不同方向旋转两次。

.
暑假学习的时候感觉这里有点难就先跳过了,现在差不多理解了它的意思,后续需要大量题来补充和提高二叉树部分的想法和思路。

标签:10,结点,中序,二叉树,先序,root,节点,2021
来源: https://blog.csdn.net/m0_55995088/article/details/120687816