【正确答案】(1)数据结构
考虑设计若干条不带头结点的单链表,用于容纳同义词;然后设计一个指针数组,其中的元素分别指向各个单链表。具体定义如下:
typedef int DataType;
typedef int KeyType;
struct ZipNode;
typedef struct ZipNode*PZipNode;
struct ZipNodef /*每条单链表上的结点结构定义*/
KeyType key;
DataType value;
PZipNode link;
};
struct ZipHashDic{ /*散列表结构定义*/
PZipNode linklist[REGION_LEN];
int m: /*存放基本区域长度REGION_LEN*/
};
typedefstruct ZipHashDic*PZipHashDic;/*指向散列表的指针类型定义*/
(2)算法
int h(KeyType key){ /*散列函数*/
return key/%REGION_LEN;
/*取模,REGION_LEN应该取为一个素数*/
}
PZipHashDic createEmptyDic_zip(){
PZipHashDic pzhash==(PZipHashDic)malloc(sizeof(struct ZipHashDic));
int i:
pzhash->m=REGION_LEN;
for(i=0;i<pzhash->m;i++)pzhash->linklist[i]=NULL;
return pzhash;
}
void insert_zip(PZipHashDic pzhash,KeyType key){ /*插入算法*/
PZipNode p,q;
int d=h(key);
if(pzhash->linklist[d]==NULL){
/*如果单链表为空,向单链表中插入第一个元素*/
p=(PZipNode)malloc(sizeof(struct ZipNode));
p->key=key;
p->link=NULL;
pzhash->linklist[d]=p;
return;
}
q=pzhash->linklist[d];
if(q->key==key)return;
/*如已有此元素则不再插入,否则就插入在单链表的最后*/
while(q->link!=NULL){
if(q->link->key==key)return;
q=q->link;
}
p=(PZipNode)malloc(sizeof(struct ZipNode));
p->key=key;
p->link=NULL;
q->link=p;
}
void delete_zip(PZipHashDic pzhash,KeyType key){ /*删除算法*/
PZipNode p,q;
int d=h(key);
if(pzhash->linklist[d]==NULL)return;
p=pzhash->linklist[d];
if(p->key==key){
/*如果要删除的元素是单链表的第一个*/
pzhash->linklist[d]=p->link;
free(p);
return;
}
while(p->link!=NULL)
if(p->link->key==key){
q=p->link;
p->link==q->link;
free(q);
return;
}
}
(3)代价分析
由于结合了数组和链表的特点,使插入和删除操作所用的时间代价降低,均只由涉及的元素所在的单链表的长度(即它的同义词总数)决定。单链表的长度越短,消耗的时间也就越短。设最长单链表的长度为k,则上面两算法的时间代价均为O(k)。
【答案解析】