查找二 树与图的搜索

搜索对象是一个数据的集合(称为搜索表),除了执行搜索外,还可能执行其他操作,例如添加新元素,这样可能会改变搜索表的结构。因此,搜索表可以区分为静态搜索表(表的结构不发生改变)和动态搜索表两种情况。

常见的适用于静态搜索表的搜索方法有:顺序搜索、折半搜索、Fibonacci搜索等。

适用于动态搜索表的搜索方法有:二叉排序算法,平衡二叉搜索算法。

二叉排序树搜索

二叉排序树(Binary sort Tree,BST)又称为二叉查找(搜索)树(Binary Search Tree) 。其必须为二叉排序树或者为空树,或者满足如下性质的二叉树:

(1)若它的左子树非空,则左子树所有结点的值均小于根结点的值;

(2)若它的右子树非空,则右子树上所有结点的值均大于根结点的值;

(3)左、右子树本身又各是一颗二叉排序树。

由BST性质可得:

1)二叉排序树中任一结点x,其左(右)子树中任一结点y(若存在)的关键字必小(大)于x的关键字。

2)二叉排序树,各结点关键字是唯一的。

实际运用中,不能保证被查找的数据集中各元素的关键字互不相同,所以可将二叉排序树定义中BST性质(1)里的“小于”改为“大于等于”,或将BST性质(2)里的“大于”改为“小于等于”,甚至可同时修改这两个性质。

3)按中序遍历该树所得到的中序序列是一个递增有序序列。

二叉排序树的存储结构表示如下:

typedef int KeyType;//假定关键字类型为整数
typedef struct node {//结点类型
    KeyType key;//关键字项
    InfoType otherinfo;//其他数据域,InfoType视应用情况而定,下面不处理它
    struct node *lchild,*rchild;//左右孩子指针
} BSTNode;
typedef BSTNode *BSTree;//BSTree是二叉排序树的类型

  

B-树

当查找文件较大,且存放在磁盘等直接存取设备中时,为了减少查找过程中对磁盘的读写次数,提高查找效率,基于直接存取设备的读写操作以“页”为单位的特征。1972年提出了一种称之为B-树的多路平衡查找树。它适合在磁盘等直接存取设备上组织动态的查找表。一颗m(m>=3)阶的B-树是满足如下性质的m叉树:

(1)每个节点至少包含下列数据域:(j,P0,K1,P1,k2,……,Ki,Pi)。其中:

j为关键字总数,

Ki(1<=i<=j)是关键字,关键字序列递增有序:K1<K2<……<Ki。

Pi(0<=i<=j)是孩子指针。对于叶节点,每个Pi为空指针。

注意:

实际运用中没结束空间,叶节点可省去指针域Pi,但必须在每个结点中增加一个标志域leaf,其值为真时表示叶节点,否则为内部结点。

在每个内部结点中,假设用keys(Pi)来表示子树Pi中的所有关键字,则有keys(P0)<K1<keys(P1)<K2<……<Ki<keys(Pi),即关键字是分界点,任一关键字Ki左边子树中的所有关键字均小于Ki,右边子树中的所有关键字均大于Ki。

(2)所有叶子是在同一层,叶子层数位树的高度h。

(3)每个非根结点中所包含的关键字个数j满足:m/2-1<=j<=m-1,m为阶数。

即每个非根结点至少应该有m/2-1个关键字,至多有m-1个关键字。因为每个内部结点的个数正好是关键字总数加1,故每个非根的内部结点至少有m/2棵子树,至多有m棵子树。

(4)若树非空,则根至少有1个关键字,故若根不是叶子,则它至少有2棵子树。根至多有m-1个关键字,故至多有m棵子树。

B-树的结点规模

B-树的算法执行时间主要是由读写磁盘的次数来决定的,每次读写尽可能多的信息可提高算法的执行速度。

B-树的结点规模一般是一个磁盘页,而结点中的所包含的关键字及其孩子的数目取决于磁盘页的大小。

注意:

1)对于磁盘上一颗较大B-树,通常每个结点拥有的孩子数目(即结点的度数)m为50至2000不等。

2)一颗度为m的B-树称为m阶B-树。

3)选取较大的结点度数可降低树的高度,以及减少查找任意关键字所需的磁盘访问次数。

B-树的存储结构

#define Max 1000    //结点中关键字的最大数目:Max=m-1,m是B-树的阶
#define Min 500        // 非根结点中关键字的最小数目:Min=m/2-1
typedef int KeyType;//KeyType应由用户定义
typedef struct node {//结点定义中省略了指向关键字代表的记录的指针
    int keynum;//结点中当前拥有的关键字的个数,keynum<<Max
    KeyType key[Max+1];//关键字向量为key[1……keynum],key[0]不用
    struct node *parent;    //指向双亲结点
    struct node *son[Max+1];//孩子指针向量为son[0……keynum]
 }BTreeNode;
typedef BTreeNode *BTree;

  

广度优先搜索

搜索图常用方法有深度优先搜索和广度优先搜索两种。它们对无向图和有向图都适用。

广度优先搜索(BFS)类似于树按层次遍历的过程。广泛应用于求解问题的最短路径、最少步骤、最优方法等方面。

广度优先搜索遍历图的过程中以V为起始点,由近及远,依次访问和V右路径相通且路径长度为1,2……的顶点。

BFS(图g,顶点s)
{
    队列Q;
    for(顶点u in g.所有顶点)    u.状态=未访问;
    s.状态=准备访问;
    s.访问深度=0;
    Q.入队(s);
    while( Q.非空() )
    {
     顶点u=Q.出队();
     for(顶点v in u.所有邻接点)
     {
      if(v.状态==未访问)
      {
        v.状态=准备访问;
        v.访问深度=v.访问深度+1;
        v.前趋点=u;
        Q.入队(v);
       }
     }
    u.状态=已访问;
   }
}

  

深度优先搜索

DFS类似于树的先根遍历,是树的先根遍历的推广。常用于游戏软件开发中。深度优先搜索的核心思想是在搜索到尽头时,用栈记住下一步的走向。

DFS(图g,顶点s)
{
  s.状态=正在访问;

  for(顶点v in s.所有邻接点)
  {
   if(s.状态 == 未访问)
       DFS(g,v);
   }

  s.状态=已访问;
}

  在遍历图的时候,对图中每个顶点至多调用一次深度优先搜索,遍历图的过程实质上是对每个顶点查找其邻接点的过程,其耗费的时间取决于所采用的数据结构。当用邻接矩阵存储图时,查找一个顶点的邻接点所需时间为O(n)(n表示图中顶点数目),则总的时间复杂度为T(n)=O(n^2).

---------------------------------------------------------------------------------

参考文献《算法分析与设计》 (C++描述)   清华大学出版社 石志国

时间: 2024-10-30 09:33:36

查找二 树与图的搜索的相关文章

查找(二):彻底理解红黑树和平衡查找树

平衡查找树 在之前的二分搜索和二叉查找树中已经能够很好地解决查找的问题了,但是它们在最坏情况下的性能还是很糟糕,我们可以在查找二叉树中,每次动态插入或删除某结点时,都重新构造为完全二叉树,但是这样代价太大,所以就引出了平衡查找树. 详细的数学定义就不给出了,因为既不直观也记不住,直接给出一个平衡二叉树的图: 相信这个图一看就明白了,平衡查找树(以下简称BST或2-3查找树),下面给出一些基本的定义: 一棵2-3查找树或为一棵空树,或由一下结点组成: 2-结点,含有一个键(及其对应的值)和两条链接

使用OpenCV查找二值图中最大连通区域

http://blog.csdn.net/shaoxiaohu1/article/details/40272875 使用OpenCV查找二值图中最大连通区域 标签: OpenCVfindCoutours 2014-10-19 22:31 2802人阅读 评论(0) 收藏 举报  分类: 图像与OpenCV(15)  版权声明:本文为shaoxiaohu原创文章,欢迎转载,请注明出处,谢谢. 上一篇博文中介绍了matlab查找最大连通区域的方法,OpenCV函数中也有类似的函数与之对应,findC

爪哇国新游记之二十五----图及其遍历查找

代码: import java.util.ArrayList; import java.util.Collections; import java.util.HashSet; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; import java.util.Set; // 顶点类 class Vertex{ String name;// 名称 boolean visited;// 是否已访问

算法导论 第二十二章:图的搜索

图有两种标准的表示方法,即邻接矩阵和邻接表(通常邻接矩阵用于稠密图,邻接表用于稀疏图).如下: 对于图的搜索有两种方法:深度优先搜索 & 广度优先搜索. 广度优先搜索(Breadth-first search) 广度优先搜索是将已发现和未发现顶点之间的边界沿其广度方向向外扩展.亦即算法首先会发现和s距离为k的所有点,然后才会发现和s距离为k+1的其他顶点. 伪代码: EG: 运行时间:O(V+E). 深度优先遍历(Depth-first search) 在深度优先搜索中,对于最新发现的顶点,如果

kd树的构建以及搜索

构建算法 k-d树是一个二叉树,每个节点表示一个空间范围.表1给出的是k-d树每个节点中主要包含的数据结构. 表1 k-d树中每个节点的数据类型 域名 数据类型 描述 Node-data 数据矢量 数据集中某个数据点,是n维矢量(这里也就是k维) Range 空间矢量 该节点所代表的空间范围 split 整数 垂直于分割超平面的方向轴序号 Left k-d树 由位于该节点分割超平面左子空间内所有数据点所构成的k-d树 Right k-d树 由位于该节点分割超平面右子空间内所有数据点所构成的k-d

【暖*墟】 #树与图# 深度优先遍历入门知识点

[一. 时间戳(dfn)] 什么是时间戳? 就是每个位置被访问到的次序. 比如说我们对一棵树进行深搜,在深搜中访问的相应次序就被我们称为时间戳. [二. 树的dfs序] 1.dfs序的作用 维护一系列树上的问题,解决一棵树上的所有后代结点信息的更改和祖先结点有关改变, 通过dfs来记录树的每个顶点的出入时间戳,来控制它子树上的所有结点的状态的更新. 用 L[ i ],R[ i ] 来记录这个祖先结点控制后代结点的区间. 即dfs序的特点就是:每个节点编号x在序列中恰好出现两次. 一棵子树的dfs

在二维有序数组中搜索某个数(存在否、出现次数)

在二维有序数组中搜索某个数(存在否.出现次数) 问题描述 写出一个高效的算法来搜索m×n矩阵中的值,返回这个值出现的次数. 这个矩阵具有以下特性: 每行中的整数从左到右是排序的. 每一列的整数从上到下是排序的. 在每一行或每一列中没有重复的整数. 样例 考虑下列矩阵: [ [1, 3, 5, 7], [2, 4, 7, 8], [3, 5, 9, 10] ] 给出target = 3,返回 2 实现思路 由于数组每行从左到右是有序的,每列从上到下是有序的,因此可以考虑从二维数组的右上角开始搜索.

SDUT 3374 数据结构实验之查找二:平衡二叉树

数据结构实验之查找二:平衡二叉树 Time Limit: 400MS Memory Limit: 65536KB Submit Statistic Problem Description 根据给定的输入序列建立一棵平衡二叉树,求出建立的平衡二叉树的树根. Input 输入一组测试数据.数据的第1行给出一个正整数N(n <= 20),N表示输入序列的元素个数:第2行给出N个正整数,按数据给定顺序建立平衡二叉树. Output 输出平衡二叉树的树根. Example Input 5 88 70 61

Linux命令之pstree - 以树状图显示进程间的关系

本文链接:http://codingstandards.iteye.com/blog/842156   (转载请注明出处) 用途说明 pstree命令以树状图显示进程间的关系(display a tree of processes).ps命令可以显示当前正在运行的那些进程的信息,但是对于它们之间的关系却显示得不够清晰.在Linux系统中,系统调用fork可以创建子进程,通过子shell也可以创建子进程,Linux系统中进程之间的关系天生就是一棵树,树的根就是进程PID为1的init进程. 常用参