问答题 设计一种散列法表示的字典存储方法,适合使用拉链法解决碰撞,给出在这种存储结构中实现字典元素的插入和删除算法。
【正确答案】(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)。
【答案解析】