二叉树及堆;二叉搜索树

首先明确:完全二叉树;满二叉树;平衡二叉树是根据树的样子不同命名的。而堆;二叉搜索树(二叉查找树)是根据节点的值大小命名的。
动态查找树主要有:二叉查找树(Binary Search Tree),平衡二叉查找树(Balanced Binary Search Tree),红黑树(Red-Black Tree ),B-tree/B±tree/ B*-tree (B~Tree)。前三者是典型的二叉查找树结构,其查找的时间复杂度O(log2N)与树的深度相关,那么降低树的深度自然会提高查找效率。B 树是为了磁盘或其它存储设备而设计的一种多叉(B树每个内结点有多个分支,即多叉)平衡查找树。
三种特殊二叉树(Binary Tree)的概念:
完全二叉树:除了最高层以外,其余层节点个数都达到最大值,并且最高层节点都优先集中在最左边。
满二叉树:除了最高层有叶子节点,其余层无叶子,并且非叶子节点都有2个子节点。
平衡二叉树:一棵空树或左右两个子树的高度差的绝对值不超过1,并且左右两个子树都是一棵平衡二叉树。
在这里插入图片描述
图1:完全二叉树
在这里插入图片描述
图2:满二叉树
四种常见遍历方法:
中序遍历:左-根-右,例如图1中的遍历结果:D->B->E->A->C
先序遍历:根-左-右,例如图1中的遍历结果:A->B->D->E->C
后序遍历:左-右-根,例如图1中的遍历结果:D->E->B->C->A
层序遍历:即从第一层开始,逐层遍历,每层遍历按照从左到右遍历。例如1图中的遍历结果:A->B->C->D->E
二叉搜索树:对于任意一个节点,其值不小于左子树的任何节点,且不大于右子树的任何节点(反之亦可),则为二叉搜索树。如果按照中序遍历,其遍历结果是一个有序序列。因此,二叉搜索树又称为二叉排序树。
在这里插入图片描述
图3:二叉搜索树
最小堆:每一个节点的值都小于或等于其两个子节点的值
最大堆:每一个节点的值都大于或等于其两个子节点的值
红黑树:是一种近似平衡的二叉查找树,最坏情况下时间复杂度为O(log(n))
AVL树是最先发明的自平衡二叉查找树。在AVL树中任何节点的两个儿子子树的高度最大差别为一,最坏情况下时间复杂度为O(log(n))。
B树:B 树是为了磁盘或其它存储设备而设计的一种多叉(下面你会看到,相对于二叉,B树每个内结点有多个分支,即多叉)平衡查找树。非叶节点至多可以有m-1个关键字,至少可以有ceil(n/2)-1个,根节点可以至少有一个关键字。
参考:https://blog.csdn.net/v_july_v/article/details/6530142
在这里插入图片描述
例题:在一个空的5阶B-树中依次插入关键字序列{6,8,15,16,22,10,18,32,20},插入完成后,关键字6所在结点包含的关键字个数为( 3 )
n阶B-树,每个结点中关键字个数范围为ceil(m/2) - 1 ~ m-1个,因此为2-4个,插入时首先插入6,8,15,16;
再插入22时结点个数大于4,因此取15为中间结点拆分,变成15 - (6,8),(16,22),继续插入10,18,32变成15 - (6,8,10),(16,18,22,32),再插入20时结点个数大于4,取20为中间结点拆分,合并到根节点上变为(15,20) - (6,8,10),(16,18),(22,32)
根节点可以至少有一个关键字。根据这个原则,可以画出5阶B树的构建过程,如下图所示:
在这里插入图片描述

### 单链表中头指针和尾指针的概念及用法 #### 头指针概念 在单链表中,头指针是一个特殊的指针变量,它始终指向链表的第一个节点。如果链表为空,则头指针为`NULL`。头指针的存在使得可以方便地遍历整个链表并执行各种操作,比如查找、插入或删除节点。 对于带头结点的单链表而言,头指针实际上是指向一个不存储实际数据的哑元节点(哨兵),该节点位于真正意义上的第一个有效元素之前[^4]。 ```c typedef struct Node { int data; struct Node *next; } Node; Node* head = NULL; // 初始化空列表时设置head为NULL ``` #### 尾指针概念 尾指针同样也是一个特殊类型的指针,在某些情况下被用来指向链表最后一个节点的位置。当仅设有尾指针而无显式的头部引用时,通常意味着这是一个循环链表;在这种设计下,可以通过尾部快速定位到首项从而形成闭环结构[^5]。 ```c // 对于带有尾指针的循环链表定义如下: typedef struct _ListNode { ElemType data; struct _ListNode *next; } ListNode; typedef ListNode* CyclicList; CyclicList tail = NULL; // 初始状态下tail也为NULL表示空表 ``` #### 使用方法 - **创建新节点**: 当需要新增加一个节点至链表末端时,先分配内存空间给新的节点对象,并将其`next`字段置为`NULL`(如果是普通单链表)或者是重新连回到链表开头(若是循环形式)[^1]。 - **更新尾指针**: 插入完成后应调整当前记录下来的最后位置即尾指针使其指向最新加入的那个成员上。这一步骤简化了许多涉及追加的操作流程因为无需再从前往后扫描整条链条寻找终点。 - **遍历与访问**: 虽然尾指针主要用于辅助构建特定模式下的链接序列,但在读取过程中一般还是依赖于由头指针出发逐步前进的方式完成逐个项目的检视工作[^3]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值