搜索(1):符号表


1. 符号表的概念

搜索:我们把处理的数据划分为记录或数据项(item),每个数据项都有一个用于搜索的关键字(key)。搜索的目标是找出目标关键字所匹配的数据项。搜索的目的是访问这个数据项(不仅是关键字)中的信息。
符号表:它是一种数据结构,其中数据项含有关键字。它支持两个基本的操作:插入一个新的数据项和搜索返回给定关键字的数据项。(字典)

如何处理符号表中相同关键字?
在符号表的实现中应注意考虑可能楚翔相同关键字的数据项。在某些应用(如身份证信息)中不允许出现重复关键字,此时,关键字可以作为句柄。其他包含大量相同关键字的应用(如文档数据库),关键字搜索会有多个查询结果。有以下三种处理方法:
(1)在主数据结构中的关键字保持都不同,即将具有相同关键字的数据项组合到一起,形成一个链接。search 时返回所有给定关键字对应的所有数据项;delete 时删除所有给定关键字对应所有数据项。
(2)在主数据结构中关键字可以相同,search 时返回任意一个给定关键字的数据项,delete 时删除任意一个。
(3)给每一个数据项添加另外的标识符(唯一),搜索和删除时给出关键字和标识符

2. 符号表的顺序搜索

根据应用的期望时间和空间要求,有四种符号表的实现方法:
(1)有序数组:频繁使用排序或选择 select
(2)有序链表:频繁使用排序,频繁选择时应选用有序数组,链表只能顺序访问
(3)无序数组:频繁插入
(4)无序链表:频繁插入
其中,链表较之数组的优点是,不需预测出表的大小,缺点是额外占用空间(存放链接),且不能高效支持选择操作。

2.1 基于有序数组的符号表

插入时,犹如插入排序时,将较大元素向后移动位置,将新的元素插入数组中

static Item *st;
static int N;
void STinit(int maxN) 
  { st = malloc((maxN)*sizeof(Item)); N = 0; }
int STcount() 
  { return N; }
void STinsert(Item item)
  { int j = N++; Key v = key(item);
    while (j>0 && less(v, key(st[j-1])))
      {  st[j] = st[j-1]; j--; }
    st[j] = item;
  }
Item STsearch(Key v)
  { int j;
    for (j = 0; j < N; j++)
      {
        if (eq(v, key(st[j])))
            return st[j];
        if (less(v, key(st[j]))) 
            break;
      }
    return NULLitem;
  }
Item STselect(int k)
  { return st[k]; }
void STsort(void (*visit)(Item))
  { int i;
    for (i = 0; i < N; i++) visit(st[i]); 
  }

2.2 基于无序链表的符号表

//不完整代码,仅供简略查看原理
#include <stdio.h>
#define Key(A) (A - 'a')
#define NULLItem -1
typedef struct Element Item;
typedef struct Element
{
    int key;
    char data;
};
typedef struct STnode* link;
typedef struct STnode
{
    Item item;
    link next;
} STnode;

static int N; //表元素的个数
static link head, z;
link New(Item item, link next)
{
    link x = (link)malloc(sizeof(*x));
    x->item = item;
    x->next = next;
    return x;
}

link STInit()
{
    link x = (z = new(NULLItem, NULL));//z为哑节点
    N = 0;
    return x;
}
//=============Search===============
Item searchR(link t, Key v)
  { 
    if (t == z) 
    return NULLitem;
    if (eq(key(t->item), v)) 
        return t->item;
    return searchR(t->next, v);
  }
Item STsearch(Key v)
  { return searchR(head, v); }


link STInsert(Item item)
{
    head = New(item, head);
    N++;
}

3. 参考资料

《算法:C语言实现》P307 - P316

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值