数据结构——二叉树的操作

这里我们主要讲二叉排序树的操作:

什么是二叉排序树?

  1. 或者是一棵空树
  2. 或者是具有一下性质的二叉树:

    a.若它的左子树不空,则左子树上所有结点的值均小于它的根节点的值;

    b.若它的右子树不空,则右子树上所有结点的值均大于它的根结点的值;

    c.它的左、右子树也分别为二叉排序树

Tip : 中序(左根右)遍历二叉排序树会得到一个关键字的递增有序序列


二叉排序树的操作——查找

查找步骤:

  1. 若查找的关键字等于根节点,成功
  2. 若查找的关键字小于根节点,查找其左子树
  3. 若查找的关键字大于根节点,查找其右子树
  4. 在左、右子树上重复操作1~3

算法思想:

  1. 若二叉排序树为空,则查找失败,返回空指针
  2. 若二叉排序树非空,将给定的值 key 与根节点的关键字 T->data 进行比较:

    a.若 key 等于 T->data,则查找成功,返回根节点地址;

    b.若 key 小于 T->data ,则进一步查找其左子树;

    c.若 key 大于 T->data,则进一步查找其右子树。

算法描述:

BSTree SearchBST(BSTree T,KeyType key)
{
   if((!T) || key == T->data)
       return T;
   else if (key < T->data)
       return SearchBST(T->lchild,key); //在左子树中继续查找
   else
       return SearchBST(T->rchild,key);  //在右子树中继续查找
} // SearchBST

查找的性能分析:

平均查找长度和二叉树的形态有关,即,

最好:log2n(形态匀称,与二分查找的判定树相似)

最坏: (n+1)/2(单支树)

问题:如何提高二叉排序树的查找效率? —— 尽量让二叉树的形状均衡

平衡二叉树(AVL树)

  • 所有结点的左、右子树深度之差的绝对值≤ 1
  • 左、右子树是平衡二叉树

对于一棵有 n 个结点的AVL树,其高度保持在 O(log2n) 数量级,ASL也保持在 O(log2n) 量级。


树的平衡旋转!

如果在一棵 AVL 树中插入一个新结点,就有可能造成失衡,此时必须重新调整树的结构,

使之恢复平衡。我们称调整平衡过程为平衡旋转

  • LL平衡旋转
  • RR平衡旋转
  • LR平衡旋转
  • RL平衡旋转

LL平衡旋转:

若在A的左子树的左子树上插入结点,使A的平衡因子从1增加至2,需要进行一次顺时针旋转。

(以B为旋转轴)

=========》



RR平衡旋转:

若在A的右子树的右子树上插入结点,使A的平衡因子从-1增加至-2,需要进行一次逆时针旋转。

(以B为旋转轴)

=========》



LR平衡旋转:

若在A的左子树的右子树上插入结点,使A的平衡因子从1增加至2,需要先进行逆时针旋转,再顺时针旋转。

(以插入的结点C为旋转轴)

==①==》==②==》

解释:这里步骤①是根据二叉排序树的特点 A>C>B来做的,因为C>B所以将B作为C的左孩子。

步骤②就是LL平衡转换



RL平衡旋转:

若在A的右子树的左子树上插入结点,使A的平衡因子从-1增加至-2,需要先进行顺时针旋转,再逆时针旋转。

(以插入的结点C为旋转轴)

==①==》==②==》

解释:这里步骤①是根据二叉排序树的特点B>C>A来做的,因为B>C所以将B作为C的右孩子。

步骤②就是RR平衡转换


二叉排序树的操作——插入

插入步骤:

  1. 若二叉树为空,则插入节点应为根结点
  2. 若二叉树非空,继续在其左、右子树上查找:

    a.树中已经有了要插入的节点,则不再插入

    b.树中还没有要插入的节点:查找直至某个叶子结点的左子树或右子树为空为止,

    则插入结点应为该叶子结点的左孩子或右孩子

注意:插入的元素一定在叶子结点上


二叉排序树的操作——删除

要求:

1.将因删除结点而断开的二叉链表重新链接起来

2.防止重新链接后的树的高度增加

删除总结:

  • 删除叶结点,只需将其双亲结点指向它的指针清零,再释放它即可。
  • 被删结点缺右子树,可以拿它的左子女结点顶替它的位置,再释放它。
  • 被删结点缺左子树,可以拿它的右子女结点顶替它的位置,再释放它。
  • 被删结点左、右子树都存在,可以在它的右子树中寻找中序下的第一个结点(关键码最小),

    用它的值填补到被删结点中,再来处理这个结点的删除问题。

实例:

时间: 2024-10-14 00:51:58

数据结构——二叉树的操作的相关文章

数据结构 二叉树大部分操作的实现

#ifndef BINTREE_H_INCLUDED #define BINTREE_H_INCLUDED #include <iostream> #include <queue> #include <stack> #include <string.h> using namespace std; template<class Type> class BinTree; template<class Type> class BinTree

数据结构——二叉树的遍历

"树"是一种重要的数据结构,本文浅谈二叉树的遍历问题,採用C语言描写叙述. 一.二叉树基础 1)定义:有且仅有一个根结点,除根节点外,每一个结点仅仅有一个父结点,最多含有两个子节点,子节点有左右之分. 2)存储结构 二叉树的存储结构能够採用顺序存储,也能够採用链式存储,当中链式存储更加灵活. 在链式存储结构中,与线性链表类似,二叉树的每一个结点採用结构体表示,结构体包括三个域:数据域.左指针.右指针. 二叉树在C语言中的定义例如以下: struct BiTreeNode{ int c;

数据结构二叉树——建立二叉树、中序递归遍历、非递归遍历、层次遍历

数据结构二叉树-- 编写函数实现:建立二叉树.中序递归遍历.借助栈实现中序非递归遍历.借助队列实现层次遍历.求高度.结点数.叶子数及交换左右子树. ("."表示空子树) #include<stdio.h> #include<stdlib.h> //***********二叉树链表节点结构 typedef char DataType; typedef struct Node {  DataType data;  struct Node*LChild;  struc

搜索二叉树的操作

搜索二叉树的数据结构定义: /*二叉搜索树的结构定义*/ typedef struct TreeNode* SearchTree; typedef struct TreeNode* Position; struct TreeNode { int Element; SearchTree Left; SearchTree Right; } 搜索二叉树的插入操作: SearchTree Insert(int x, SearchTree T) { if(T == NULL)//空树 { T = mall

浅谈数据结构-二叉树

浅谈数据结构-二叉树 二叉树是树的特殊一种,具有如下特点:1.每个结点最多有两颗子树,结点的度最大为2.2.左子树和右子树是有顺序的,次序不能颠倒.3.即使某结点只有一个子树,也要区分左右子树. 一.特殊的二叉树及特点 1.斜树 所有的结点都只有左子树(左斜树),或者只有右子树(右斜树).这就是斜树,应用较少 2.满二叉树 所有的分支结点都存在左子树和右子树,并且所有的叶子结点都在同一层上,这样就是满二叉树.就是完美圆满的意思,关键在于树的平衡. 根据满二叉树的定义,得到其特点为: 叶子只能出现

第十章 基本数据结构——二叉树

摘要 书中第10章10.4小节介绍了有根树,简单介绍了二叉树和分支数目无限制的有根树的存储结构,而没有关于二叉树的遍历过程.为此对二叉树做个简单的总结,介绍一下二叉树基本概念.性质.二叉树的存储结构和遍历过程,主要包括先根遍历.中根遍历.后根遍历和层次遍历. 1.二叉树的定义 二叉树(Binary Tree)是一种特殊的树型结构,每个节点至多有两棵子树,且二叉树的子树有左右之分,次序不能颠倒. 由定义可知,二叉树中不存在度(结点拥有的子树数目)大于2的节点.二叉树形状如下下图所示: 2.二叉树的

POJ 3367 Expressions(数据结构-二叉树)

Expressions Description Arithmetic expressions are usually written with the operators in between the two operands (which is called infix notation). For example, (x+y)*(z-w) is an arithmetic expression in infix notation. However, it is easier to write

二叉树插入操作

/* 功能:将一个节点插入到二叉树中节点的子节点中 输入: p,c ,RL p:节点将插入到p所指向的节点的子节点中 c:指向待插入的节点 RL:为0表示插入到左子树,为1表示插入到右子树 输出:bool */ template<typename T> bool BinaryTree<T>::InsertChild(BTNode<T> *p,BTNode<T> *c,int RL) { if(p) { if(RL==0) //插入到p的左节点 { c->

[数据结构] 二叉树的建立及其基本操作

如图: 代码: #include <iostream> #include <stdio.h> #include <algorithm> #include <string.h> using namespace std; char ch; typedef struct BinNode { char data; struct BinNode *lchild,*rchild; }BinNode,*BinTree; //二叉树链式存储结构 void CreateBin