查找

来源:互联网 发布:淘宝客定向计划 编辑:程序博客网 时间:2024/04/30 16:13

1.静态查找表的抽象数据类型

ADT StaticSearchTable {
数据对象D:D是具有相同特性的数据元素的集合。每个数据元素含有类型相同的关键字,可唯       一标识数据元素。
数据关系R:数据元素同属一个集合。
基本操作P:
Create(&ST, n);
操作结果:构造一个含n个数据元素的静态查找表ST。
Destroy(&ST);
初始条件:静态查找表ST存在;
操作结果:销毁表ST。
Search(ST, key);
初始条件:静态查找表ST存在,key为和查找表中元素的关键字类型相同的给定值;
操作结果:若ST中存在其关键字等于key的数据元素,则函数值为该元素的值或在表中的位置,      否则为“空”。
Traverse(ST, Visit());
初始条件:静态查找表ST存在,Visit是对元素操作的应用函数;
操作结果:按某种次序对ST的每个元素调用函数Visit()一次且仅一次,一旦Visit()失败,则       操作失败。
} ADT StaticSearchTable
 
2.静态查找表的顺序存储结构

typedef struct {
ElemType *elem; // 数据元素存储空间基址,建表时按实际长度分配,0号单元留空
int length; // 表的长度
} SSTable;

3. 静态查找表的查找方法
 
   在静态搜索表中, 利用数组元素的下标作为数据对象的存放地址。搜索算法根据给定值x,  在数组中进行搜索。直到找到x在数组中的位置或可确定在数组中找不到x为止。
(1) 顺序查找
   可以顺序表或线性链表表示静态查找表,算法为:
   int Search_Seq(SSTable ST, KeyType key) {
   // 在顺序表ST中顺序查找其关键字等于key的数据元素。若找到,则函数值为该元素在
   // 表中的位置,否则为0。
  ST.elem[0].key = key; // “哨兵”,目的省略对下标越界的检查,提高算法执行速度。
   for (i=ST.length; ST.elem[i].key!=key; --i); // 从后往前找
   return i; // 找不到时,i为0
   } // Search_Seq
   该查找算法简单,但平均查找长度较大,特别不适用于表长较大的查找表。
(2) 折半查找
   可以有序表表示静态查找表,算法为:
   int Search_Bin ( SSTable ST, KeyType key ) {
   // 在有序表ST中折半查找其关键字等于key的数据元素。
   // 若找到,则函数值为该元素在表中的位置,否则为0。
   low = 1; high = ST.length; // 置区间初值
   while (low <= high) {
   mid = (low + high) / 2;
   if (EQ (key , ST.elem[mid].key) )
   return mid; // 找到待查元素
   else if ( LT (key , ST.elem[mid].key) )
   high = mid - 1; // 继续在前半区间进行查找
   else low = mid + 1; // 继续在后半区间进行查找
    }
   return 0; // 顺序表中不存在待查元素
   } // Search_Bin
(3)分块查找
   分块查找也称索引顺序查找,即先由索引确定记录所在的块,然后在块中顺序查找。
   分块查找的平均查找长度等于在索引表中查找所在块的平均查找长度Lb与在块表中查找     元素的平均查找长度Lw之和。 ASLbs=Lb+Lw
  查找算法:
  int Blocksch(mainlist A,indexlist B,int m, KeyType K){
  //利用主表A和大小为m的索引表B分块查找关键字为K的记录
  int i,j;
  for (i=0;i<m;i++) //在索引表中顺序查找关键字为K所对应的索引项
  if(K<=B[i].index)
  break;
  if(i==m) //若i=m,则表明查找失败,返回-1
  return –1;
  j=B[i].start; //在已经找到的第i个子表中顺序查找关键字为K的记录
  while(j<B[i].start+B[i].length)
  if (K==A[j].key)
  break;
  else
  j++;
  if(j<B[i].start + B[i].length) // 若查找成功则返回元素的下标位置,否则返回-1
  return j;
  else
  return –1;
  } //Blocksch

2,二叉排序树

       所谓的二叉排序树,指的是一颗空树,或者一颗具有如下特性的二叉树: 为空

        <1>,若根结点的左子树 不为空,则其左子树的所有结点的值均小于右子树的值。

         <2>,若根结点的有子树不为空,则其右子树的所有节点的值均大于左子树的值。

         <3>,根结点的左右子树本身又是一颗子树。

         二叉排序树的查找过程:
         1,若二叉树是空树,则查找失败
         2,若x等于此二叉树的根结点的值,则查找成功。
         3,若x的值小于根结点,则访问左子树。
         4,若x的值大于根结点,则访问有子树。

         二叉排序树的插入和生成
         二叉排序树的过程是一个向空树一个个结点实现的,向一颗二叉排序树中插入一个节点s的步骤如下:
        <1>.若二叉树是空树,则将该节点作为根结点,直接插入。
        <2>,若s的数据域的值等于该二叉树排序树的数据域的值,则返回,不需要重复插入。
        <3>,若S的数据域小于该二叉树的根结点的数据域的值,则把s所指的节点到根结点的左子树中。
        4>,若S的数值域的值大于二叉排序树的根结点数据域的值,则把s所指节点插入到根结点的右子树中。

        二叉排序树的删除:

       二叉排序树删除,必须进行查找,并且在查找的过程中,保护好待删除结点,及其双亲结点地址。 
       1,若待删除的节点是叶子结点,则直接删除
       2,若待删除的节点只有左子树而没有右子树,则用将左子树放到删除结点的位置。
       3,若待删除的节点只有右子树而没有左子树,则用将右子树放到删除节点的位置。 
        4,若待删除的节点有左子树和右子树,则有两种调整方法:<1>,将右子树放置删除节点的位置,并把删除节点的左右子树放到待删除节点的位置,并把代数删除节点的 左    子树放到右子树中序遍历第一个节点的左子树;<2>,将待删除节点的的右子树遍历的第一个节点放到删除节点的位置,并且按照2的方法,删除这个节点。

       平衡二叉树:

        平衡二叉树:
       1,可以是空树
       2,设左右子树分别为TL,TR,深度分别为hl,hr,其子树仍然是平衡二叉树,并且|hl-hr|<=1

 

 

      

原创粉丝点击