基于树的查找

基于树的查找法就是把待查找的表组织成树形结构再进行查找的方法。基于树的查找最常用的是基于二叉树的查找。

二叉排序树的创建和插入操作

编写算法,要求根据一个元素序列创建一棵二叉排序树,并将给定的元素插入到二叉排序树中,使其仍然是一棵二叉排序树。

【二叉排序树的定义】

二叉排序树也称为二叉树查找树,它或者是一棵空二叉树,或者具有以下性质:
#如果二叉树的左子树不为空,则左子树上的每一个结点的元素值都小于其对应根结点元素值;
#如果二叉树的右子树不为空,则右子树上的每一个结点的元素值都小于其对应根结点元素值;

#该二叉树的左子树和右子树也满足上述两种性质,即左子树和右子树也是一颗二叉排序树。

显然这是一个递归的二叉排序树定义。如下图所示为一个二叉排序树。

图中的树每个结点的元素值都大于其所有左子树结点的元素值,且小于其所有右子树中结点元素值。例如,80大于左孩子的结点元素值70,小于右孩子结点元素值87。

【算法思想】

二叉排序树的插入操作过程其实就是二叉排序树的建立过程。二叉排序树的插入操作从根结点开始,首先要检查当前结点元素是否是要找的元素,如果是则不进行插入操作。否则,将结点插入到查找失败时结点的左指针或右指针处。在算法的实现过程中,需要设置一个指向下一个要访问结点的双亲指针parent,就是需要记下前驱结点的位置,以便在查找失败时进行插入操作。

初始时,当前结点指针cur为空,则说明查找失败,将插入的第1个元素作为根结点元素,然后让parent指针指向根结点元素。如果parent->data小于要插入的根结点元素x,则需要将parent的左指针指向x,使x成为parent的左孩子结点元素。如果parent->data大于要插入的根结点元素x,则需要将parent的右指针指向x,使x成为parent的右孩子结点元素。在整个二叉排序树的插入过程中,插入操作都是在叶子结点处进行的。

【示例】

假设一个元素序列为55、43、66、88、18、80、33、21、72,根据二叉排序树的插入算法思想,对应的二叉排序树插入过程如图所示

从图中可以看出,通过中序遍历二叉排序树,可以得到一个有序的元素序列18,21,33,43,55,66,72,80,88。

code

#include<stdio.h>
#include<malloc.h>
#include <iostream>typedef struct Node    /*二叉排序树的类型定义*/
{int data;struct Node *lchild, *rchild;
}BiTreeNode, *BiTree;
BiTree BSTSearch(BiTree T, int x);
int BSTInsert(BiTree *T, int x);
void InOrderTraverse(BiTree T);
void main()
{BiTree T = NULL, p;int table[] = { 55,33,44,66,99,77,88,22,11 };int n = sizeof(table) / sizeof(table[0]);int x, i;for (i = 0; i < n; i++)BSTInsert(&T, table[i]);printf("中序遍历二叉排序树得到的序列为:\n");InOrderTraverse(T);printf("\n请输入要查找的元素:");scanf("%d", &x);p = BSTSearch(T, x);if (p != NULL)printf("二叉排序树查找:元素%d查找成功.\n", x);elseprintf("二叉排序树查找:没有找到元素%d.\n", x);system("pause");
}
BiTree BSTSearch(BiTree T, int x)
/*二叉排序树的查找操作。
如果找到元素x,则返回指向结点的指针,否则返回NULL*/
{BiTreeNode *p;if (T != NULL)                      /*如果二叉排序树不为空*/{p = T;while (p != NULL){if (p->data == x) /*如果找到,则返回指向该结点的指针*/return p;else if (x < p->data) /*如果关键字小于p指向的结点的值,则在左子树中查找*/p = p->lchild;elsep = p->rchild; /*如果关键字大于p指向的结点的值,则在右子树中查找*/}}return NULL;
}
int BSTInsert(BiTree *T, int x)
/*二叉排序树的插入操作.
如果树中不存在元素x,则将x插入到正确的位置并返回1,否则返回0*/
{BiTreeNode *p, *cur, *parent = NULL;cur = *T;while (cur != NULL){if (cur->data == x)   /*如果二叉树中存在元素为x的结点,则返回0*/return 0;parent = cur;              /*parent指向cur的前驱结点*/if (x < cur->data)        /*如果关键字小于p指向的结点的值,则在左子树中查找*/cur = cur->lchild;elsecur = cur->rchild;         /*如果关键字大于p指向的结点的值,则在右子树中查找*/}p = (BiTreeNode*)malloc(sizeof(BiTreeNode));   /*生成结点*/if (!p)exit(-1);p->data = x;p->lchild = NULL;p->rchild = NULL;if (!parent)                      /*如果二叉树为空,则第一结点成为根结点*/*T = p;else if (x < parent->data)       /*如果x小于parent指向的结点元素,则将x成为parent的左孩子*/parent->lchild = p;else                        /*如果x大于parent指向的结点元素,则将x成为parent的右孩子*/parent->rchild = p;return 1;
}
void InOrderTraverse(BiTree T)
/*中序遍历二叉排序树*/
{if (T)                             /*如果二叉排序树不为空*/{InOrderTraverse(T->lchild);       /*中序遍历左子树*/printf("%4d", T->data);             /*访问根结点*/InOrderTraverse(T->rchild);     /*中序遍历右子树*/}
}

结果:

【特点】
#基于二叉排序树的查找算法分为插入操作和查找操作两个部分。
#插入操作不需要移动结点,仅需要移动结点指针。
【效率分析】

该树的平均查找长度为:

该树的平均查找长度为:

二叉排序树的平均查找长度和树的形态有关,对于n个结点,最坏的情况下,平均查找长度为(n+1)/2,最好的情况下,平均查找长度为log2(n)。

查找算法4——基于树的查找相关推荐

  1. 二叉排序树(BST查找、插入、删除、遍历)——基于树的查找(一)

    二叉排序树 二叉排序树(Binary Search Tree,BST):又称二叉查找树,是一种高效的数据结构. 定义 二叉排序树或者是一棵空树,或者是具有如下特性的二叉树: 若左子树不空,则左子树上所 ...

  2. 数据结构之查找算法:B+树

    查找算法:B+树 B+树的定义:(数据库中应用) B树与B+树的区别: B+树的定义:(数据库中应用) 例: ps:这是一颗四阶树,所以每个节点最多可以有4颗子树 ps:每个节点的关键字都不能小于2 ...

  3. 数据结构之查找算法:B树

    查找算法:B树 思维导图: B树的定义: 例: n个关键字,阶数为m,高度为h的B树的高度计算 基本操作: 查找: 插入: 删除: 对终端节点的删除: 对非终端节点的删除: 思维导图: B树的定义: ...

  4. Python查找算法(三)------ 插值查找

    算法简介 插值查找时根据要查找的关键字key与查找表中最大最小记录的关健字比较后的查找方法. 其核心就在于插值的计算公式: (key-a[low])/(a[high]-a[low])*(high-lo ...

  5. php折半查找算法,PHP如何实现折半查找算法

    本文主要介绍了PHP实现的折半查找算法,简单描述了折半查找的原理,并结合实例形式分析了php采用递归与非递归方式实现折半查找算法的相关操作技巧,需要的朋友可以参考下,希望能帮助到大家. 定义:折半查找 ...

  6. java快速查找算法_Java实现的快速查找算法示例

    本文实例讲述了Java实现的快速查找算法.分享给大家供大家参考,具体如下: 快速查找算法,可以根据想要找的是第几个大的数,每次循环都能固定下来一个数在数组完整排完序之后的位置,每次循环都能定一个数的位 ...

  7. python中顺序查找法例子_Python查找算法(一)------ 顺序查找

    查找算法  --  简介 查找(Searching)就是根据给定的某个值,在查找表中确定一个其关键字等于给定值的数据元素. 查找表(Search Table):由用一类型的数据元素构成的集合 关健字( ...

  8. python二分法查找算法_python之路-二分法查找

    楔子 如果有这样一个列表,让你从这个列表中找到66的位置,你要怎么做? l = [2,3,5,10,15,16,18,22,26,30,32,35,41,42,43,55,56,66,67,69,72 ...

  9. php大数组查找算法,PHP简单的数组查找算法分享

    PHP中对于数组的查找可以用顺序查找或二分法查找.其中顺序查找比较简单,就是逐个比较查找.但缺点也较明显,如果查找的元素恰巧在最后一个,循环的次数过多. 1.顺序查找算法描述 在数组中逐个查找,确认是 ...

最新文章

  1. armitage识别不了漏洞_Shiro RememberMe 漏洞检测的探索之路
  2. java定义一个方法,向控制台输出一个整数的阶乘
  3. Java建造者模式详解
  4. MySQL(14)--- WHERE 子句
  5. 牛客网编程题03--明明的随机数
  6. 聊聊 归一化和标准化
  7. python中ht_python – 如何在Google App Engine上正确安装ht...
  8. 1.4 PuTTY和Xshell远程连接与密钥认证登录
  9. python中type(12.34)_下面代码的输出结果是
  10. html 判断为空js,JavaScript判断DIV内容是否为空的方法
  11. sql语句中having的用法
  12. 面经手册 · 第16篇《码农会锁,ReentrantLock之公平锁讲解和实现》
  13. ftp服务器挂载到手机文件夹,ftp服务器挂载到本地
  14. Mybatis北冥有鱼面试
  15. visio的替代者yEd Graph Editor
  16. 预处理工艺采用水处理过滤器的作用说明
  17. macbook usb口突然不能用 解决方法
  18. ffmpeg实用命令总结,直播流处理相关
  19. 分段函数用python表达_python文章分段
  20. vue移动电商java_《Vue.js+Koa2移动电商实战》总结

热门文章

  1. 健康之路心脏年龄测试是什么软件,健康之路20180827,陈伟伟,心脏病,测测你的心脏年龄(上)...
  2. 设置交换时间同步(NTP)Internet
  3. MobaXterm无法调出图形界面
  4. 为什么TCP握手是三次握手而不是两次
  5. hwc_layer_1
  6. 密码学03.5(SM4算法)
  7. Scikit-learn(一)
  8. 浙工大MBA提面通过顺利上岸经验分享
  9. 计算机房设计方案,机房设计要求方案
  10. 用break还是continue?