
前几节介绍的都是有关静态查找表的相关知识,从本节开始介绍另外一种查找表——动态查找表。
动态查找表中做查找操作时,若查找成功可以对其进行删除;如果查找失败,即表中无该关键字,可以将该关键字插入到表中。
8 查找结构:符号表,二叉查找树,二叉查找树的查找、插入和删除操作,avl树,高度平衡,ll, lr, rr, rl 旋转, 插入算法,时间复杂性分析,b树,m叉查找树,m叉查找树的查找,b树的定义和性质,b树的插入操作,b树的删除操作,静态散列,散列表,散列函数,溢出处理,开放寻址,链接。第8章 查找结构:符号表,二叉查找树,二叉查找树的查找、插入和删除操作,avl树,高度平衡,avl树的插入算法,avl树的时间复杂性分析,m叉查找树,m叉查找树的查找,b树的定义和性质,b树的插入操作,b树的删除操作,静态散列,散列表,散列函数,溢出处理。4 树:树和森林的概念及其表示,二叉树,二叉树性质,二叉树表示,二叉树遍历与树游标, lvr, lrv, vlr,中序游标,按层次遍历,满足性问题,线索二叉树,线索,中序遍历线索二叉树,将结点插入线索二叉树,选择树,胜者树,败者树,森林的二叉树表示及遍历,集合表示,并查集,在等价类问题中的应用。

图 1 二叉排序树
使用二叉排序树查找关键字二叉排序树中查找某关键字时,查找过程类似于次优二叉树,在二叉排序树不为空树的前提下,首先将被查找值同树的根结点进行比较,会有 3 种不同的结果:实现函数为:(运用递归的方法)
第8章 查找结构:符号表,二叉查找树,二叉查找树的查找、插入和删除操作,avl树,高度平衡,avl树的插入算法,avl树的时间复杂性分析,m叉查找树,m叉查找树的查找,b树的定义和性质,b树的插入操作,b树的删除操作,静态散列,散列表,散列函数,溢出处理。通过双链表的存储结构我们发现双链表可以反向查找结点优于单链表 ,实质上双链表就是以空间换取时间,虽然双链表具有可以反向查找数据的优点但是它也存在缺点:在插入和删除一个结点时需要维护两个指针变量,特别是在双链表的插入中指针的指向顺序是不可修改的。常见的综合应用题考点包括:二叉树的遍历算法,遍历基础上针对二叉树的一些统计和操作(比如结点数统计、左右子树对换等等),判断某棵二叉树是否二叉排序树,以上这些都要求能用递归的和非递归的算法解决,特别要重视非递归的算法,线索化后二叉树的遍历算法,如查找某结点线索化后的前驱或后继结点的算法以及给出huffman编码等等。

例如,在图 1 的二叉排序树中做查找关键字 1 的操作,当查找到关键字 3 所在的叶子结点时,判断出表中没有该关键字,此时关键字 1 的插入位置为关键字 3 的左孩子。
所以,二叉排序树表示动态查找表做插入操作,只需要稍微更改一下上面的代码就可以实现,具体实现代码为:
利用先序递归遍历算法创建二叉树并输出该二叉树的层次遍历序列。如果二叉树需要经常遍历或查找结点是需要某种遍历序列中的前驱和后继,那么采用线索二叉链表的存储结构就是非常不错的选择。8 查找结构:符号表,二叉查找树,二叉查找树的查找、插入和删除操作,avl树,高度平衡,ll, lr, rr, rl 旋转, 插入算法,时间复杂性分析,b树,m叉查找树,m叉查找树的查找,b树的定义和性质,b树的插入操作,b树的删除操作,静态散列,散列表,散列函数,溢出处理,开放寻址,链接。
8 查找结构:符号表,二叉查找树,二叉查找树的查找、插入和删除操作,avl树,高度平衡,ll, lr, rr, rl 旋转, 插入算法,时间复杂性分析,b树,m叉查找树,m叉查找树的查找,b树的定义和性质,b树的插入操作,b树的删除操作,静态散列,散列表,散列函数,溢出处理,开放寻址,链接。(19)采用逐点插入法建立序列(54,28,16,34,73,62,95,60,26,43)的二叉排序树后,查找数据元素 62 共进行&mdash。二叉排序树的深度 b.二叉排序树的结点的个数c.被查找结点的度 d.二叉排序树的存储结构(19)在具有 n 个结点的二叉排序树中查找一个结点的过程的时间复杂度约为&mdash。

图 2 二叉排序树插入过程
通过不断的查找和插入操作,最终构建的二叉排序树如图 2(5) 所示。当使用中序遍历算法遍历二叉排序树时,得到的序列为:1 2 3 5 7,为有序序列。

一个无序序列可以通过构建一棵二叉排序树,从而变成一个有序序列c语言 二叉排序树。
常见的综合应用题考点包括:二叉树的遍历算法,遍历基础上针对二叉树的一些统计和操作(比如结点数统计、左右子树对换等等),判断某棵二叉树是否二叉排序树,以上这些都要求能用递归的和非递归的算法解决,特别要重视非递归的算法,线索化后二叉树的遍历算法,如查找某结点线索化后的前驱或后继结点的算法以及给出huffman编码等等。8 查找结构:符号表,二叉查找树,二叉查找树的查找、插入和删除操作,avl树,高度平衡,ll, lr, rr, rl 旋转, 插入算法,时间复杂性分析,b树,m叉查找树,m叉查找树的查找,b树的定义和性质,b树的插入操作,b树的删除操作,静态散列,散列表,散列函数,溢出处理,开放寻址,链接。第8章 查找结构:符号表,二叉查找树,二叉查找树的查找、插入和删除操作,avl树,高度平衡,avl树的插入算法,avl树的时间复杂性分析,m叉查找树,m叉查找树的查找,b树的定义和性质,b树的插入操作,b树的删除操作,静态散列,散列表,散列函数,溢出处理。
假设要删除的为结点 p,则对于二叉排序树来说,需要根据结点 p 所在不同的位置作不同的操作,有以下 3 种可能:
1、结点 p 为叶子结点,此时只需要删除该结点,并修改其双亲结点的指针即可;
2、结点 p 只有左子树或者只有右子树,此时只需要将其左子树或者右子树直接变为结点 p 双亲结点的左子树即可;
3、结点 p 左右子树都有,此时有两种处理方式:
所有结点只有左子树叫左斜树,只有右结点叫右斜树。[例如],在图4.2(c)的b-树中删去关键字37之后,双亲b结点中剩余信息(“指针c”)应和其双亲*a结点中关键字45一起合并至右兄弟结点*e中,删除后的b-树如图4.2(d)所示。 供选择的答案: a:①是特殊的树②不是树的特殊形式③是两棵树的总称④是只有二个根结点的树形结构 b:①左子结点②右子结点③左子结点或者没有右子结点 ④兄弟 c~d: ①最左子结点②最右子结点③最邻近的右兄弟④最邻近的左兄弟⑤最左的兄弟⑥最右的兄弟e:①o(n)②o(n)③o(log2n)④o(log2n) 15、每一棵树都能唯一地转换为它所对应的二叉树,树的这种二叉树表示对树的运算带来很大的好处。


图 3 二叉排序树中删除结点(1)
2)用结点 p 的直接前驱(或直接后继)来代替结点 p,同时在二叉排序树中对其直接前驱(或直接后继)做删除操作。如图 4 为使用直接前驱代替结点 p:

图 4 二叉排序树中删除结点(2)
图 4 中,在对左图进行中序遍历时,得到的结点 p 的直接前驱结点为结点 s,所以直接用结点 s 覆盖结点 p,由于结点 s 还有左孩子,根据第 2 条规则,直接将其变为双亲结点的右孩子。
具体实现代码:(可运行)

#include<stdio.h>
#include<stdlib.h>
#define TRUE 1
#define FALSE 0
#define ElemType int
#define KeyType int
/* 二叉排序树的节点结构定义 */
typedef struct BiTNode
{
int data;
struct BiTNode *lchild, *rchild;
} BiTNode, *BiTree;
//二叉排序树查找算法
int SearchBST(BiTree T, KeyType key, BiTree f, BiTree *p) {
//如果 T 指针为空,说明查找失败,令 p 指针指向查找过程中最后一个叶子结点,并返回查找失败的信息
if (!T) {
*p = f;
return FALSE;
}
//如果相等,令 p 指针指向该关键字,并返回查找成功信息
else if (key == T->data) {
*p = T;
return TRUE;
}
//如果 key 值比 T 根结点的值小,则查找其左子树;反之,查找其右子树
else if (key < T->data) {
return SearchBST(T->lchild, key, T, p);
}
else {
return SearchBST(T->rchild, key, T, p);
}
}
int InsertBST(BiTree *T, ElemType e) {
BiTree p = NULL;
//如果查找不成功,需做插入操作
if (!SearchBST((*T), e, NULL, &p)) {
//初始化插入结点
BiTree s = (BiTree)malloc(sizeof(BiTNode));
s->data = e;
s->lchild = s->rchild = NULL;
//如果 p 为NULL,说明该二叉排序树为空树,此时插入的结点为整棵树的根结点
if (!p) {
*T = s;
}
//如果 p 不为 NULL,则 p 指向的为查找失败的最后一个叶子结点,只需要通过比较 p 和 e 的值确定 s 到底是 p 的左孩子还是右孩子
else if (e < p->data) {
p->lchild = s;
}
else {
p->rchild = s;
}
return TRUE;
}
//如果查找成功,不需要做插入操作,插入失败
return FALSE;
}
//删除函数
int Delete(BiTree *p)
{
BiTree q, s;
//情况 1,结点 p 本身为叶子结点,直接删除即可
if (!(*p)->lchild && !(*p)->rchild) {
*p = NULL;
}
else if (!(*p)->lchild) { //左子树为空,只需用结点 p 的右子树根结点代替结点 p 即可;
q = *p;
*p = (*p)->rchild;
free(q);
}
else if (!(*p)->rchild) {//右子树为空,只需用结点 p 的左子树根结点代替结点 p 即可;
q = *p;
*p = (*p)->lchild;//这里不是指针 *p 指向左子树,而是将左子树存储的结点的地址赋值给指针变量 p
free(q);
}
else {//左右子树均不为空,采用第 2 种方式
q = *p;
s = (*p)->lchild;
//遍历,找到结点 p 的直接前驱
while (s->rchild)
{
q = s;
s = s->rchild;
}
//直接改变结点 p 的值
(*p)->data = s->data;
//判断结点 p 的左子树 s 是否有右子树,分为两种情况讨论
if (q != *p) {
q->rchild = s->lchild;//若有,则在删除直接前驱结点的同时,令前驱的左孩子结点改为 q 指向结点的孩子结点
}
else {
q->lchild = s->lchild;//否则,直接将左子树上移即可
}
free(s);
}
return TRUE;
}
int DeleteBST(BiTree *T, int key)
{
if (!(*T)) {//不存在关键字等于key的数据元素
return FALSE;
}
else
{
if (key == (*T)->data) {
Delete(T);
return TRUE;
}
else if (key < (*T)->data) {
//使用递归的方式
return DeleteBST(&(*T)->lchild, key);
}
else {
return DeleteBST(&(*T)->rchild, key);
}
}
}
void order(BiTree t)//中序输出
{
if (t == NULL) {
return;
}
order(t->lchild);
printf("%d ", t->data);
order(t->rchild);
}
int main()
{
int i;
int a[5] = { 3,4,2,5,9 };
BiTree T = NULL;
for (i = 0; i < 5; i++) {
InsertBST(&T, a[i]);
}
printf("中序遍历二叉排序树:\n");
order(T);
printf("\n");
printf("删除3后,中序遍历二叉排序树:\n");
DeleteBST(&T, 3);
order(T);
}
运行结果:
中序遍历二叉排序树:
2 3 4 5 9
删除3后,中序遍历二叉排序树:
2 4 5 9
总结使用二叉排序树在查找表中做查找操作的时间复杂度同建立的二叉树本身的结构有关。即使查找表中各数据元素完全相同,但是不同的排列顺序,构建出的二叉排序树大不相同。
主要讲解工作中常用的数据结构和算法,主要内容有链表、栈、队列、树、表、排序和查找等。8 查找结构:符号表,二叉查找树,二叉查找树的查找、插入和删除操作,avl树,高度平衡,ll, lr, rr, rl 旋转, 插入算法,时间复杂性分析,b树,m叉查找树,m叉查找树的查找,b树的定义和性质,b树的插入操作,b树的删除操作,静态散列,散列表,散列函数,溢出处理,开放寻址,链接。第8章 查找结构:符号表,二叉查找树,二叉查找树的查找、插入和删除操作,avl树,高度平衡,avl树的插入算法,avl树的时间复杂性分析,m叉查找树,m叉查找树的查找,b树的定义和性质,b树的插入操作,b树的删除操作,静态散列,散列表,散列函数,溢出处理。

图 5 不同构造的二叉排序树
}不难分析,上述算法的时间复杂度同样为 o(n) 7.6.3 二叉树的线索化算法对--x 树的线索化,就是把二叉树的二叉链表存储结构中结点的所有空指针域改造成指向某结点在某种遍历序列中的直接前驱或直接后继的过程, 因此, 二叉树的线索化过程只能在对二叉树的遍历过程中进行。常见的综合应用题考点包括:二叉树的遍历算法,遍历基础上针对二叉树的一些统计和操作(比如结点数统计、左右子树对换等等),判断某棵二叉树是否二叉排序树,以上这些都要求能用递归的和非递归的算法解决,特别要重视非递归的算法,线索化后二叉树的遍历算法,如查找某结点线索化后的前驱或后继结点的算法以及给出huffman编码等等。堆排序是一种树形选择排序,在排序过程中,将a[n]看成是完全二叉树的顺序存储结构,利用完全二叉树中双亲结点和孩子结点之间的内在关系来选择最小的元素。
算法将在二值化图像的基础上寻找视频窗口下边缘的位置,如图6右侧中红色箭头所示,下边缘的定位无需精确,以能将视频窗口完整移入显示屏内为原则。3. 在“用天平和量筒测定固体和液体的密度”实验中,为测定物体的质量,调节天平横梁平衡时,发现天平的指针静止在分度盘中央刻度线的左侧,则应将横梁上的平衡螺母向__________ 调节,将一矿石标本放在已调好的天平左盘内,当天平重新平衡时右盘内的砝码和游码在标尺上的位置如图8甲所示,则矿石的质量为__________克,将矿石标本放入装有水的量筒中,量筒中水面位置的变化情况如图8乙所示,则矿石的体积为__________厘米3.这种矿石的密度为__________千克/米3.。苏州)小明在实验室用天平和量筒测量矿石的密度,他先把托盘天平放在水平桌面上,将游码移到标尺左端的零刻度线处,发现指针在图甲位置静止,接着他将天平右端的平衡螺母向左调节,使横梁在水平位置平衡,然后他用天平测量矿石的质量,示数如图乙所示,则矿石的质量为52g.最后他用量筒测量矿石的体积,示数如图丙所示,由此可得矿石的密度为2.6×103kg/m3.。
本文来自电脑杂谈,转载请注明本文网址:
http://www.pc-fly.com/a/jisuanjixue/article-101536-1.html
忽然的那一份坚强
快射炮