@quinn
2015-04-13T13:30:29.000000Z
字数 1872
阅读 2037
搜索算法
搜索:我们把处理的数据划分为记录或数据项(item),每个数据项都有一个用于搜索的关键字(key)。搜索的目标是找出目标关键字所匹配的数据项。搜索的目的是访问这个数据项(不仅是关键字)中的信息。
符号表:它是一种数据结构,其中数据项含有关键字。它支持两个基本的操作:插入一个新的数据项和搜索返回给定关键字的数据项。(字典)
如何处理符号表中相同关键字?
在符号表的实现中应注意考虑可能楚翔相同关键字的数据项。在某些应用(如身份证信息)中不允许出现重复关键字,此时,关键字可以作为句柄。其他包含大量相同关键字的应用(如文档数据库),关键字搜索会有多个查询结果。有以下三种处理方法:
(1)在主数据结构中的关键字保持都不同,即将具有相同关键字的数据项组合到一起,形成一个链接。search 时返回所有给定关键字对应的所有数据项;delete 时删除所有给定关键字对应所有数据项。
(2)在主数据结构中关键字可以相同,search 时返回任意一个给定关键字的数据项,delete 时删除任意一个。
(3)给每一个数据项添加另外的标识符(唯一),搜索和删除时给出关键字和标识符
根据应用的期望时间和空间要求,有四种符号表的实现方法:
(1)有序数组:频繁使用排序或选择 select
(2)有序链表:频繁使用排序,频繁选择时应选用有序数组,链表只能顺序访问
(3)无序数组:频繁插入
(4)无序链表:频繁插入
其中,链表较之数组的优点是,不需预测出表的大小,缺点是额外占用空间(存放链接),且不能高效支持选择操作。
插入时,犹如插入排序时,将较大元素向后移动位置,将新的元素插入数组中
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]);}
//不完整代码,仅供简略查看原理#include <stdio.h>#define Key(A) (A - 'a')#define NULLItem -1typedef 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++;}
《算法:C语言实现》P307 - P316