数据结构 二叉排序树

合集下载

数据结构c语言课设-二叉树排序

数据结构c语言课设-二叉树排序

题目:二叉排序树的实现1 内容和要求1)编程实现二叉排序树,包括生成、插入,删除;2)对二叉排序树进展先根、中根、和后根非递归遍历;3)每次对树的修改操作和遍历操作的显示结果都需要在屏幕上用树的形状表示出来。

4)分别用二叉排序树和数组去存储一个班(50 人以上)的成员信息(至少包括学号、姓名、成绩3 项),比照查找效率,并说明在什么情况下二叉排序树效率高,为什么?2 解决方案和关键代码2.1 解决方案:先实现二叉排序树的生成、插入、删除,编写DisplayBST函数把遍历结果用树的形状表示出来。

前中后根遍历需要用到栈的数据构造,分模块编写栈与遍历代码。

要求比照二叉排序树和数组的查找效率,首先建立一个数组存储一个班的成员信息,分别用二叉树和数组查找,利用clock〔〕函数记录查找时间来比照查找效率。

2.2关键代码树的根本构造定义及根本函数typedef struct{KeyType key;} ElemType;typedef struct BiTNode//定义链表{ElemType data;struct BiTNode *lchild, *rchild;}BiTNode, *BiTree, *SElemType;//销毁树int DestroyBiTree(BiTree &T){if (T != NULL)free(T);return 0;}//清空树int ClearBiTree(BiTree &T){if (T != NULL){T->lchild = NULL;T->rchild = NULL;T = NULL;}return 0;}//查找关键字,指针p返回int SearchBST(BiTree T, KeyType key, BiTree f, BiTree &p) {if (!T){p = f;return FALSE;}else if EQ(key, T->data.key){p = T;return TRUE;}else if LT(key, T->data.key)return SearchBST(T->lchild, key, T, p);elsereturn SearchBST(T->rchild, key, T, p);}二叉树的生成、插入,删除生成void CreateBST(BiTree &BT, BiTree p){int i;ElemType k;printf("请输入元素值以创立排序二叉树:\n");scanf_s("%d", &k.key);for (i = 0; k.key != NULL; i++){//判断是否重复if (!SearchBST(BT, k.key, NULL, p)){InsertBST(BT, k);scanf_s("%d", &k.key);}else{printf("输入数据重复!\n");return;}}}插入int InsertBST(BiTree &T, ElemType e){BiTree s, p;if (!SearchBST(T, e.key, NULL, p)){s = (BiTree)malloc(sizeof(BiTNode));s->data = e;s->lchild = s->rchild = NULL;if (!p)T = s;else if LT(e.key, p->data.key)p->lchild = s;elsep->rchild = s;return TRUE;}else return FALSE;}删除//某个节点元素的删除int DeleteEle(BiTree &p){BiTree q, s;if (!p->rchild) //右子树为空{q = p;p = p->lchild;free(q);}else if (!p->lchild) //左子树为空{q = p;p = p->rchild;free(q);}else{q = p;s = p->lchild;while (s->rchild){q = s;s = s->rchild;}p->data = s->data;if (q != p)q->rchild = s->lchild;elseq->lchild = s->lchild;delete s;}return TRUE;}//整棵树的删除int DeleteBST(BiTree &T, KeyType key) //实现二叉排序树的删除操作{if (!T){return FALSE;}else{if (EQ(key, T->data.key)) //是否相等return DeleteEle(T);else if (LT(key, T->data.key)) //是否小于return DeleteBST(T->lchild, key);elsereturn DeleteBST(T->rchild, key);}return 0;}二叉树的前中后根遍历栈的定义typedef struct{SElemType *base;SElemType *top;int stacksize;}SqStack;int InitStack(SqStack &S) //构造空栈{S.base = (SElemType*)malloc(STACK_INIT_SIZE *sizeof(SElemType));if (!S.base) exit(OVERFLOW);S.top = S.base;S.stacksize = STACK_INIT_SIZE;return OK;}//InitStackint Push(SqStack &S, SElemType e) //插入元素e为新栈顶{if (S.top - S.base >= S.stacksize){S.base = (SElemType*)realloc(S.base, (S.stacksize + STACKINCREMENT)*sizeof(SElemType));if (!S.base) exit(OVERFLOW);S.top = S.base + S.stacksize;S.stacksize += STACKINCREMENT;}*S.top++ = e;return OK;}//Pushint Pop(SqStack &S, SElemType &e) //删除栈顶,应用e返回其值{if (S.top == S.base) return ERROR;e = *--S.top;return OK;}//Popint StackEmpty(SqStack S) //判断是否为空栈{if (S.base == S.top) return TRUE;return FALSE;}先根遍历int PreOrderTraverse(BiTree T, int(*Visit)(ElemType e)) {SqStack S;BiTree p;InitStack(S);p = T;while (p || !StackEmpty(S)){if (p){Push(S, p);if (!Visit(p->data)) return ERROR;p = p->lchild;}else{Pop(S, p);p = p->rchild;}}return OK;}中根遍历int InOrderTraverse(BiTree T, int(*Visit)(ElemType e)) {SqStack S;BiTree p;InitStack(S);p = T;while (p || !StackEmpty(S)){if (p){Push(S, p);p = p->lchild;}else{Pop(S, p);if (!Visit(p->data)) return ERROR;p = p->rchild;}}return OK;}后根遍历int PostOrderTraverse(BiTree T, int(*Visit)(ElemType e)) {SqStack S, SS;BiTree p;InitStack(S);InitStack(SS);p = T;while (p || !StackEmpty(S)){if (p){Push(S, p);Push(SS, p);p = p->rchild;}else{if (!StackEmpty(S)){Pop(S, p);p = p->lchild;}}}while (!StackEmpty(SS)){Pop(SS, p);if (!Visit(p->data)) return ERROR;}return OK;}利用数组存储一个班学生信息ElemType a[] = { 51, "陈继真", 88,82, "黄景元", 89,53, "贾成", 88,44, "呼颜", 90,25, "鲁修德", 88,56, "须成", 88,47, "孙祥", 87, 38, "柏有患", 89, 9, " 革高", 89, 10, "考鬲", 87, 31, "李燧", 86, 12, "夏祥", 89, 53, "余惠", 84, 4, "鲁芝", 90, 75, "黄丙庆", 88, 16, "李应", 89, 87, "杨志", 86, 18, "李逵", 89, 9, "阮小五", 85, 20, "史进", 88, 21, "秦明", 88, 82, "杨雄", 89, 23, "刘唐", 85, 64, "武松", 88, 25, "李俊", 88, 86, "卢俊义", 88, 27, "华荣", 87, 28, "杨胜", 88, 29, "林冲", 89, 70, "李跃", 85, 31, "蓝虎", 90, 32, "宋禄", 84, 73, "鲁智深", 89, 34, "关斌", 90, 55, "龚成", 87, 36, "黄乌", 87, 57, "孔道灵", 87, 38, "张焕", 84, 59, "李信", 88, 30, "徐山", 83, 41, "秦祥", 85, 42, "葛公", 85, 23, "武衍公", 87, 94, "范斌", 83, 45, "黄乌", 60, 67, "叶景昌", 99, 7, "焦龙", 89, 78, "星姚烨", 85, 49, "孙吉", 90, 60, "陈梦庚", 95,};数组查询函数void ArraySearch(ElemType a[], int key, int length){int i;for (i = 0; i <= length; i++){if (key == a[i].key){cout << "学号:" << a[i].key << " 姓名:" << a[i].name << " 成绩:" << a[i].grade << endl;break;}}}二叉树查询函数上文二叉树根本函数中的SearchBST()即为二叉树查询函数。

数据结构之二叉树(BinaryTree)

数据结构之二叉树(BinaryTree)

数据结构之⼆叉树(BinaryTree)⽬录导读 ⼆叉树是⼀种很常见的数据结构,但要注意的是,⼆叉树并不是树的特殊情况,⼆叉树与树是两种不⼀样的数据结构。

⽬录 ⼀、⼆叉树的定义 ⼆、⼆叉树为何不是特殊的树 三、⼆叉树的五种基本形态 四、⼆叉树相关术语 五、⼆叉树的主要性质(6个) 六、⼆叉树的存储结构(2种) 七、⼆叉树的遍历算法(4种) ⼋、⼆叉树的基本应⽤:⼆叉排序树、平衡⼆叉树、赫夫曼树及赫夫曼编码⼀、⼆叉树的定义 如果你知道树的定义(有限个结点组成的具有层次关系的集合),那么就很好理解⼆叉树了。

定义:⼆叉树是n(n≥0)个结点的有限集,⼆叉树是每个结点最多有两个⼦树的树结构,它由⼀个根结点及左⼦树和右⼦树组成。

(这⾥的左⼦树和右⼦树也是⼆叉树)。

值得注意的是,⼆叉树和“度⾄多为2的有序树”⼏乎⼀样,但,⼆叉树不是树的特殊情形。

具体分析如下⼆、⼆叉树为何不是特殊的树 1、⼆叉树与⽆序树不同 ⼆叉树的⼦树有左右之分,不能颠倒。

⽆序树的⼦树⽆左右之分。

2、⼆叉树与有序树也不同(关键) 当有序树有两个⼦树时,确实可以看做⼀颗⼆叉树,但当只有⼀个⼦树时,就没有了左右之分,如图所⽰:三、⼆叉树的五种基本状态四、⼆叉树相关术语是满⼆叉树;⽽国际定义为,不存在度为1的结点,即结点的度要么为2要么为0,这样的⼆叉树就称为满⼆叉树。

这两种概念完全不同,既然在国内,我们就默认第⼀种定义就好)。

完全⼆叉树:如果将⼀颗深度为K的⼆叉树按从上到下、从左到右的顺序进⾏编号,如果各结点的编号与深度为K的满⼆叉树相同位置的编号完全对应,那么这就是⼀颗完全⼆叉树。

如图所⽰:五、⼆叉树的主要性质 ⼆叉树的性质是基于它的结构⽽得来的,这些性质不必死记,使⽤到再查询或者⾃⼰根据⼆叉树结构进⾏推理即可。

性质1:⾮空⼆叉树的叶⼦结点数等于双分⽀结点数加1。

证明:设⼆叉树的叶⼦结点数为X,单分⽀结点数为Y,双分⽀结点数为Z。

数据结构-二叉排序树

数据结构-二叉排序树

二叉排序树操作一、设计步骤1)分析课程设计题目的要求2)写出详细设计说明3)编写程序代码,调试程序使其能正确运行4)设计完成的软件要便于操作和使用5)设计完成后提交课程设计报告(一)程序功能:1)创建二叉排序树2)输出二叉排序树3)在二叉排序树中插入新结点4)在二叉排序树中删除给定的值5)在二叉排序树中查找所给定的值(二)函数功能:1) struct BiTnode 定义二叉链表结点类型包含结点的信息2) class BT 二叉排序树类,以实现二叉排序树的相关操作3) InitBitree() 构造函数,使根节点指向空4) ~BT () 析构函数,释放结点空间5) void InsertBST(&t,key) 实现二叉排序树的插入功能6) int SearchBST(t,key) 实现二叉排序树的查找功能7) int DelBST(&t,key) 实现二叉排序树的删除功能8) void InorderBiTree (t) 实现二叉排序树的排序(输出功能)9) int main() 主函数,用来完成对二叉排序树类中各个函数的测试二、设计理论分析方法(一)二叉排序树定义首先,我们应该明确所谓二叉排序树是指满足下列条件的二叉树:(1)左子树上的所有结点值均小于根结点值;(2)右子数上的所有结点值均不小于根结点值;(3)左、右子数也满足上述两个条件。

根据对上述的理解和分析,我们就可以先创建出一个二叉链表结点的结构体类型(struct BiTNode)和一个二叉排序树类(class BT),以及类中的构造函数、析构函数和其他实现相关功能的函数。

(二)插入函数(void InsertBST(&t,key))首先定义一个与BiTNode<k> *BT同一类型的结点p,并为其申请空间,使p->data=key,p->lchild和p->rchild=NULL。

数据结构二叉排序树

数据结构二叉排序树

05
13
19
21
37
56
64
75
80
88
92
low mid high 因为r[mid].key<k,所以向右找,令low:=mid+1=4 (3) low=4;high=5;mid=(4+5) div 2=4
05
13
19
low
21
37
56
64
75
80
88
92
mid high
因为r[mid].key=k,查找成功,所查元素在表中的序号为mid 的值
平均查找长度:为确定某元素在表中某位置所进行的比 较次数的期望值。 在长度为n的表中找某一元素,查找成功的平均查找长度:
ASL=∑PiCi
Pi :为查找表中第i个元素的概率 Ci :为查到表中第i个元素时已经进行的比较次数
在顺序查找时, Ci取决于所查元素在表中的位置, Ci =i,设每个元素的查找概率相等,即Pi=1/n,则:
RL型的第一次旋转(顺时针) 以 53 为轴心,把 37 从 53 的左上转到 53 的左下,使得 53 的左 是 37 ;右是 90 ,原 53 的左变成了 37 的右。 RL型的第二次旋转(逆时针)
一般情况下,假设由于二叉排序树上插入结点而失去 平衡的最小子树的根结点指针为a(即a是离插入结点最 近,且平衡因子绝对值超过1的祖先结点),则失去平衡 后进行调整的规律可归纳为下列四种情况: ⒈RR型平衡旋转: a -2 b -1 h-1 a1
2.查找关键字k=85 的情况 (1) low=1;high=11;mid=(1+11) / 2=6
05
13
19
21

二叉排序树的构造方法

二叉排序树的构造方法

二叉排序树的构造方法二叉排序树又称二叉查找树,是一种经典的数据结构,它具有快速的插入、删除和查找等操作。

在实际应用中,二叉排序树被广泛地使用,因此了解二叉排序树的构造方法至关重要。

本文将介绍二叉排序树的构造方法,帮助读者深入理解这一数据结构。

一、二叉排序树基本概念二叉排序树是一种二叉树,每个节点包含一个值,并且满足以下性质:1. 左子树上所有节点的值均小于其父节点的值;2. 右子树上所有节点的值均大于其父节点的值;3. 左右子树也分别为二叉排序树。

根据上述性质,可以得出二叉排序树的中序遍历结果为有序序列。

这一特点使得二叉排序树成为一种非常有效的数据结构,用于快速查找和排序。

二、二叉排序树的构造方法在构造二叉排序树时,一般采用递归或循环遍历的方法。

下面将分别介绍这两种构造方法。

1. 递归构造方法递归构造方法是一种常见且直观的构造二叉排序树的方式。

其基本原理为,将新节点插入到当前节点的左子树或右子树上,直至找到合适的位置。

具体流程如下所示:(1)若二叉排序树为空,直接将新节点作为根节点插入;(2)若新节点值小于当前节点值,则递归地将其插入到左子树上;(3)若新节点值大于当前节点值,则递归地将其插入到右子树上。

通过递归构造方法,可以很方便地构造出一棵满足二叉排序树性质的树。

2. 循环构造方法循环构造方法是另一种构造二叉排序树的方式,通过使用迭代的方式,逐步构建二叉排序树。

其基本思路为:(1)从根节点开始,若树为空,则直接将新节点插入为根节点;(2)若树不为空,则利用循环遍历的方式,找到新节点应插入的位置,直至找到合适的叶子节点;(3)将新节点插入到找到的叶子节点的左子树或右子树上。

循环构造方法相对于递归构造方法,更加迭代化,适合于对二叉排序树进行迭代构造和遍历。

三、二叉排序树构造方法的实现在实际编程中,可以通过使用递归或循环的方式,实现二叉排序树的构造。

下面将简要介绍二叉排序树构造方法的实现过程。

1. 递归实现递归实现二叉排序树的构造方法一般通过编写递归函数,不断地将新节点插入到当前节点的左子树或右子树上。

介绍二叉排序树的结构和特点

介绍二叉排序树的结构和特点

介绍二叉排序树的结构和特点二叉排序树,也称为二叉搜索树或二叉查找树,是一种特殊的二叉树结构,其主要特点是左子树上的节点都小于根节点,右子树上的节点都大于根节点。

在二叉排序树中,每个节点都存储着一个关键字,而且所有的关键字都不相同。

二叉排序树的结构如下:1.根节点:二叉排序树的根节点是整个树的起始点,其关键字是最大的。

2.左子树:根节点的左子树包含着小于根节点关键字的所有节点,且左子树本身也是一个二叉排序树。

3.右子树:根节点的右子树包含着大于根节点关键字的所有节点,且右子树本身也是一个二叉排序树。

二叉排序树的特点如下:1.有序性:二叉排序树的最重要特点是有序性。

由于左子树上的节点都小于根节点,右子树上的节点都大于根节点,所以通过中序遍历二叉排序树,可以得到一个有序的序列。

2.快速查找:由于二叉排序树是有序的,所以可以利用二叉排序树进行快速查找操作。

对于给定的关键字,可以通过比较关键字与当前节点的大小关系,逐步缩小查找范围,最终找到目标节点。

3.快速插入和删除:由于二叉排序树的有序性,插入和删除操作比较简单高效。

插入操作可以通过比较关键字的大小关系,找到合适的位置进行插入。

删除操作可以根据不同情况,分为三种情况处理:删除节点没有子节点、删除节点只有一个子节点和删除节点有两个子节点。

4.可以用于排序:由于二叉排序树的有序性,可以利用二叉排序树对一组数据进行排序。

将数据依次插入二叉排序树中,然后再通过中序遍历得到有序序列。

二叉排序树的优缺点如下:1.优点:(1)快速查找:通过二叉排序树可以提供快速的查找操作,时间复杂度为O(log n)。

(2)快速插入和删除:由于二叉排序树的有序性,插入和删除操作比较简单高效。

(3)可以用于排序:通过二叉排序树可以对一组数据进行排序,时间复杂度为O(nlog n)。

2.缺点:(1)受数据分布影响:如果数据分布不均匀,可能导致二叉排序树的高度增加,从而降低了查找效率。

(2)不适合大规模数据:对于大规模数据,二叉排序树可能会导致树的高度过高,从而影响了查找效率。

二叉排序树查找的递归算法

二叉排序树查找的递归算法

二叉排序树查找的递归算法介绍二叉排序树(Binary Search Tree),也称二叉查找树、有序二叉树或排序二叉树,是一种常用的数据结构。

它具有以下特点:•每个节点都包含一个键值和对应的数据。

•左子树中的所有节点的键值都小于根节点的键值。

•右子树中的所有节点的键值都大于根节点的键值。

•左右子树也分别是二叉排序树。

二叉排序树支持高效的查找、插入和删除操作,其中查找操作是利用递归实现的。

本文将详细介绍二叉排序树查找的递归算法。

二叉排序树的定义二叉排序树的定义如下:class TreeNode:def __init__(self, key, data):self.key = keyself.data = dataself.left = Noneself.right = Noneclass BinarySearchTree:def __init__(self):self.root = None在二叉排序树中,每个节点都是一个TreeNode对象,包含键值key和对应的数据data。

left和right分别指向左子树和右子树的根节点。

树的根节点由BinarySearchTree对象的root属性表示。

二叉排序树查找的递归算法二叉排序树的查找操作是利用递归实现的,其具体算法如下:1.如果待查找的键值等于当前节点的键值,返回当前节点的数据。

2.如果待查找的键值小于当前节点的键值,递归在左子树中查找。

3.如果待查找的键值大于当前节点的键值,递归在右子树中查找。

4.如果在左子树或右子树中找不到对应的键值,则返回空。

下面是二叉排序树查找的递归算法的代码实现:def search_recursive(node, key):if node is None or node.key == key:return node.dataelif key < node.key:return search_recursive(node.left, key)else:return search_recursive(node.right, key)在上述代码中,node表示当前节点,key表示待查找的键值。

数据结构:第9章 查找2-二叉树和平衡二叉树

数据结构:第9章 查找2-二叉树和平衡二叉树
NODE *t; char x; {if(t==NULL)
return(NULL); else
{if(t->data==x) return(t);
if(x<(t->data) return(search(t->lchild,x));
else return(search(t->lchild,x)); } }
——这种既查找又插入的过程称为动态查找。 二叉排序树既有类似于折半查找的特性,又采用了链表存储, 它是动态查找表的一种适宜表示。
注:若数据元素的输入顺序不同,则得到的二叉排序树形态 也不同!
讨论1:二叉排序树的插入和查找操作 例:输入待查找的关键字序列=(45,24,53,45,12,24,90)
二叉排序树的建立 对于已给定一待排序的数据序列,通常采用逐步插入结点的方 法来构造二叉排序树,即只要反复调用二叉排序树的插入算法 即可,算法描述为: BiTree *Creat (int n) //建立含有n个结点的二叉排序树 { BiTree *BST= NULL;
for ( int i=1; i<=n; i++) { scanf(“%d”,&x); //输入关键字序列
– 法2:令*s代替*p
将S的左子树成为S的双亲Q的右子树,用S取代p 。 若C无右子树,用C取代p。
例:请从下面的二叉排序树中删除结点P。
F P
法1:
F
P
C
PR
C
PR
CL Q
CL QL
Q SL
S PR
QL S
SL
法2:
F
PS
C
PR
CL Q
QL SL S SL
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

9.6.2 哈希函数的构造方法
构造哈希函数的目标:
哈希地址尽可能均匀分布在表空间上——均 匀性好; 哈希地址计算尽量简单。
考虑因素:
函数的复杂度; 关键字长度与表长的关系; 关键字分布情况; 元素的查找频率。
一、直接地址法 取关键字或关键字的某个线性函数值为哈希地址 即: H(key) = key 或: H(key) = a* key + b 其中,a, b为常数。 例:1949年后出生的人口调查表,关键字是年份 年份 1949 1950 1951 … 人数 … … … …
9.4 二叉排序树
1.定义:
二叉排序树(二叉搜索树或二叉查找树) 或者是一棵空树;或者是具有如下特性的二叉树
(1) 若它的左子树不空,则左子树上所有结点的 值均小于根结点的值;
(2) 若它的右子树不空,则右子树上所有结点 的值均大于等于根结点的值; (3) 它的左、右子树也都分别是二叉排序树。
例如:
H(key)
通常设定一个一维数组空间存储记录集合,则 H(key)指示数组中的下标。
称这个一维数组为哈希(Hash)表或散列表。 称映射函数 H 为哈希函数。 H(key)为哈希地址
例:假定一个线性表为: A = (18,75,60,43,54,90,46) 假定选取的哈希函数为
hash3(key) = key % 13
H(key) = key + (-1948) 此法仅适合于: 地址集合的大小 = = 关键字集合的大小
二、数字分析法
假设关键字集合中的每个关键字都是由 s 位数 字组成 (u1, u2, …, us),分析关键字集中的全体, 并从中提取分布均匀的若干位或它们的组合作为 地址。 例如:有若干记录,关键字为 8 位十进制数, 假设哈希表的表长为100, 对关键字进行分析, 取随机性较好的两位十进制数作为哈希地址。
ASL = (1 + 2 * 2 + 3 * 3)/6 =14/6
例:关键字序列:(12, 24, 37, 45, 53, 90)。
其二叉排序树为:
12 24
ASL = (1 + 2 + 3 + 4 + 5 + 6)/6
= 21/6
二叉排序树的性能取决于树 的形态,而二叉树的形态取决于 插入结点的顺序。 构造一棵接近理想平衡树的 二叉排序树?
查找不成功:
查找61: H(61)= 61%13= 9
如果 key1 ≠ key2, 但
H(key1) = H(key2)
这种现象称为“冲突”,称 key1 和 key2 为同义词。 在实际应用中,应尽量选择均匀的哈希函 数来减少冲突。
冲突不能避免时,选定一个解决冲突的方 法。
发生冲突与下列三个因素有关:
30
20 35
某结点的前驱一 定在它的左子树 的最右下方
80
40 90 85
32
前驱结点 被删结点
88
以其前驱替代之,然后 再删除该前驱结点
5. 二叉排序树的查找分析
比较次数 = 被查结点所在的层次数。 二叉排序树的性能取决于树的形态,而二叉树的 形态取决于插入结点的顺序。
关键字序列:(45,24,53,12,37,90) 45 24 12 37 53 90
{13,24,37,90,53,28,98}
插入点 插入后结果
13 24
13 A 24 B 13 13 24
失衡原因
调整
RR型
24
B
37
37
13 A 37
90
13
24 37 90
24
24 A 90 B
53
13
-2 37
RL型
13 A 37
53
C 90 B
53 C
-2
24 A 53 37 C B 90
3. 二叉排序树的构造
特点:树结构在查找的过程中动态生成。
每次插入的结点只能成为新的叶子结点
例:关键字序列为 {45,24,53,12,14,90 }
45
24 53 90 14
中序遍历:12,14,24,45,53,90
12
(1) 插入算法: status ins_bstree(BiTree &bt,BiTree s){
30 20 10 25 35
50
80 40 66 85 90
23
不 是二叉排序树。
88
对二叉排序树进行中序遍历,得到一个有序序列
2. 二叉排序树的查找算法:
若二叉排序树为空,则查找不成功; 否则 1)若给定值等于根结点的关键字,则 查找成功;
2)若给定值小于根结点的关键字,则 继续在左子树上进行查找; 3)若给定值大于根结点的关键字,则 继续在右子树上进行查找。
A BR AL BL
X
AL<A<BL<B<BR
1 0 B
A AR CR
X
C
LR型
BL
B CL
X
A -1
C BL CL
X -1 A
CR
X
AR
BL<B<CL<C< CR< A<AR
C
A AL CL
X
B 0
AL C CL CR
X X
RL型
B -1 CR
X
BR
BR
AL<A<CL<C< CR< B<BR
例:按下列关键字的次序生成一棵AVL树。
RL型
A 24 13
37 C 53 B 28 90
28
13
28
37
98
13
24 28
-2 53 A 90 B
RR型
24
37 90
13
98
28
53
98Βιβλιοθήκη 9.6 哈希表9.6.1 什么是哈希表
哈希表的基本思想: “一次”查找成功。
ASL的T(n)=O(1)。
映射函数 H
关 键 字 集 合 地 址 空 间
(1)装填因子(load factor): =
n (负载因子) m
m为hash表的长度,n为填入的记录数。
越大,冲突的可能性越大。 越小,冲突的可能性会减小,但空间的利用率变低。
为兼顾两者, 在 [0.6,0.9]范围内为宜。 (2) 与采用的散列函数有关。
(3) 与解决冲突的方法有关。
方法选择的好坏也将减少或增加发生冲突的可能性。
六、 随机数法
设定哈希函数为:
例如: 二叉排序树 50
30
20 40
80
90
35
32 查找关键字 = 50 , 35 , 90 , 95 ,
85
88
二叉链表类型定义:
typedef struct BiTNode{
KeyType key;
…… //其它成员
struct BiTNode *lchild; struct BiTNode *rchild; } BiTNode,*BiTree;
此方法仅适合于: 能预先估计出全体关键字的每一位上各 种数字出现的频度。
三、平方取中法
将k平方后的中间几位取为哈希地址。位数由表长决定
例1:时间 8:40:02。m=84002, (m)2=705633604.
例2:四位字母标识符的hash地址,地址空间为0~ 999
用两位数字01~ 26表示对应的26个字母, 如:AABB的内部代码:01010202 关键字 KEYA KEYB AKEY BKEY 内部代码 11052501 11052502 01110525 02110525 (内部代码)2 122157778355001 122157800460004 001233265775625 004454315775625 H(key) 778 800 265 315
二叉排序树的查找:
BiTree bstsrch(BiTree bt,KeyType k){
//二叉排序树的存储结构为二叉链表,函数返回结点的 //关键字为k的指针,若查找不成功,返回空指针
if (t==NULL)return NULL; else if(bt→key==k) return(bt) else if(bt→key < k ) return(bstsrch(bt→rchild,k)) else return(bstsrch(bt→lchild,k)); }
0 30
0 53
0 63
是平衡树 问:平衡树是理想平衡树吗? 不是平衡树
如何检测二叉树是否失去平衡?
当插入一个新结点时,重新计算从新插入的 结点到根结点的路径上所包含结点的平衡因 子(bf),如果某一结点的 bf 的绝对值超 过1,则二叉树失去平衡。
1 -1 3 1 3 -2 3 7 2 4 0 1
若根据哈希函数把元素存储到哈希表H[13]
中,则存储映象为:
0 1 2 3 4 5 6 7 8 9 10 11 12
H
54
43 18
46 60
75
90
0
1
2
3
4
5
6
7
8
9 10 11
12
H
54
43 18
46 60
75
90
哈希表的查找
同插入元素一样。如从表中查找关键字为60 的元素时,只要利用上面的函数计算出地址 H(60) = 60 % 13 = 8
4. 二叉排序树的删除算法
删除一个结点后,仍是二叉排序树。
可分三种情况讨论:
(1) 被删除的结点是叶子; (2) 被删除的结点只有左子树或者只有右子树; (3) 被删除的结点既有左子树,也有右子树。
相关文档
最新文档