往往不做集合的并、交、差运算,而经常需要判定某个元素是否在给定集合中,并且对集合作插入、删除操作。
把字典定义为名字-属性对的组合,根据问题的不同,可以为名字和属性赋予不同的意义。
典型的字典组织方式有线性表、跳表、散列表
字典的抽象数据类型:
const int DefaultSize=26 template <class Name,class Attribute> Class Dictionary{ //对象:一组名字属性对,其中名字是唯一的 public: Dictionary(int size=DefaultSize); bool Member(Name name); Attribute *search(Name name); void Insert(Name name,Attribute attr); void Remove(Name name); }
用有序链表表示字典
链表中的每个结点表示字典的一个元素,各个结点按照结点中保存的关键码kl非递减链接,搜索一般不要搜索整个表
关键码可重复,搜索和删除操作只会操作遇到的第一个结点
在有n个结点的有序链表中,搜索、插入、删除操作的时间复杂度均为O(n)
#include <iostream> #include <assert.h> using namespace std; //E是元素的数据类型,它也是一个类,有自己的一些属性,其中包括K。K则是关键码的数据类型,在跳表中也用类定义 template <class E,class K> struct ChainNode { E data; ChainNode<E, K> *link; ChainNode():link(NULL){}; ChainNode(E &el, ChainNode<E, K> *next = NULL):data(el),link(next){}; }; template <class E,class K> class SortedChain{ public: SortedChain(){ first=new ChainNode<E,K>; assert(first!=NULL); } ~SortedChain(); ChainNode<E,K> *Search(const K kl)const; void Insert(const K kl,E& el); bool Remove(const K kl,E& el); ChainNode<E,K> *Begin(){return first->link;} ChainNode<E,K> *Next(ChainNode<E,K> *current)const{ if(current!=NULL) return current->link; else return NULL; }; private: ChainNode<E,K> *first; }; template <class E,class K> ChainNode<E,K> *SortedChain<E,K>::Search(const K kl)const{ //搜索关键码为kl的元素 ChainNode<E,K> *p=first->link; while(p!=NULL && p->data<kl) p=p->link; if(p!=NULL && p->data==kl) return p; else return NULL; }; template <class E,class K> void SortedChain<E,K>::Insert(const K kl,E& el){ ChainNode<E,K> *p=first->link,*pre=first,*newNode; while(p!=NULL && p->data<kl){ pre=p; p=p->link; } if(p!=NULL && p->data==kl){ p->data=el; return; } newNode=new ChainNode<E,K>(kl,el); if(newNode==NULL){ cerr<<"存储分配失败!"<<endl; exit(1); } newNode->link=p; pre->link=newNode; }; template <class E,class K> bool SortedChain<E,K>::Remove(const K kl,E& el){ ChainNode<E,K> *p=first->link,*pre=first; while(p!=NULL && p->data<kl){ pre=p; p=p->link; } if(p!=NULL && p->data==kl){ pre->link=p->link; el=p->data; delete p; return true; } else return false; //关键码不存在 }; //假设每个元素的数据类型E为person class person{ friend void main(void); public: person& operator=(long kl){ID_number=kl;return *this;} bool operator<(long kl){return(ID_number<kl);} bool operator<(person& pr){return(ID_number<pr.ID_number);} bool operator>(long kl){return(ID_number>kl);} bool operator>(person& pr){return(ID_number>pr.ID_number);} bool operator==(long kl){return(ID_number==kl);} bool operator==(person& pr){return(ID_number==pr.ID_number);} private: long ID_number; //关键码ID_number即为K,数据类型为long }