线性表的两种实现

1.顺序表的实现

template<typename E>
class AList:public List<E>{
private:
   int maxSize;
   int listSize;
   int curr;//光标落在当前位置的后面
   E* listArray;
public:
   AList(int size=defaultSize){
      maxSize=size;
      listSize=curr=0;
      listArray=new E[maxSize];
   }
   ~AList(){  delete [] listArray; }
   void clear(){
      delete [] listArray;
      listSize=curr=0;
      listArray=new E[maxSize];
   }
   void insert(const E& it){
      Assert(listSize<maxSize,"List capacity exceeded");
      for(int i=listSize;i>curr;i--)
         listArray[i]=listArray[i-1];
      listAray[curr]=it;
      listSize++;
   }
   void append(const E& it){
      Assert((curr>=0)&&(curr<listSize),"No element");
      E it=listArray[curr];
      for(int i=curr;i<listSize-1;i++)
         listArray[i]=listArray[i+1];
      listSize--;
      return it;
   }
   void moveToStart(){  curr=0; }
   void moveToEnd(){  curr=listSize; }
   void prev() { if( curr!=0)  curr--;}
   void next() { if( curr<listSize) curr++;}
   int length() const {return listSize;}
   int currPos() const {return curr;}
   void moveToPos(int pos){
      Assert((pos>=0)&&(pos<=listSize),"Pos out of range");
      curr=pos;
   }
   const E& getValue() const {
      Assert((curr>=0)&&(curr<listSize),"No current element");
      return listArray[curr];
   }
};

2.链表实现

光标始终落在curr所代表的当前位置后。

(1)单链表结点类定义

template <typename E> class Link {
public:
   E element;
   Link *next;
   Link(const E& elemval,Link * nextval=NULL)
      { element=elemval;  next=nextval;}
   Link(Link* nextval=NULL) { next=nextval;}
};

(2)链表实现



template <typename E> class LList:public List<E>{
private:
   Link<E>* head;
   Link<E>* tail;
   Link<E>* curr;
   int cnt;

   void init(){
      curr=tail=head=new Link<E>;
      cnt=0;
   }
   void removeall(){
      while(head!=NULL){
         curr=head;
         head=head->next;
         delete curr;
      }
   }
public:
   LList(int size=defaultSize) { init(); }
   ~LList() { removeall(); }
   void print() const;
   void clear() { removeall();init(); }
   void insert(const E& it){
      curr->next=new Link<E>(it,curr->next);
      if(tail==curr) tail=curr->next;
      cnt++;
   }
   void append(const E& it){
      tail=tail->next=new Link<E>(it,NULL);
      cnt++;
   }
   E remove(){
     Assert(curr->next!=NULL,"No element");
     E it=curr->next->element;
     Link<E>* ltemp=curr->next;
     if (tail==curr->next) tail=curr;
     curr->next=curr->next->next;
     delete ltemp;
     cnt--;
     return it;
   }
   void moveToStart() { curr=head; }
   void moveToEnd() { curr=tail; }
   void prev(){
      if(curr==head) return;
      Link<E>* temp=head;
      while( temp->next!=curr)
         temp=temp->next;
      curr=temp;
   }
   void next() { if (curr!=tail) curr=curr->next; }
   int length() const { return cnt; }
   int currPos() const{
      Link<E>* temp=head;
      int i;
      for(i=0;curr!=temp;i++)
         temp=temp->next;
      return i;
   }
   void moveToPos(int pos){
      Assert((pos>=0)&&(pos<=cnt),"Position out of range");
     curr=head;
     for(int i=0;i<pos;i++)  curr=curr->next;
   }
   const E& getValue() const {
      Assert(curr->next!=NULL,"No value");
      return curr->next->element;
   }
};

为缩短线性表的运行时长,可以使用C++操作符重载new和delete.因为重载后的new/delete操作符所需时间约是系统存储分配和回收管理操作的十分之一。重载方法如下:

template <typename E> class Link {
private:
   static Link<E>* freelist;
public:
   E element;
   Link *next;
   Link(const E& elemval,Link * nextval=NULL)
      { element=elemval;  next=nextval;}
   Link(Link* nextval=NULL) { next=nextval;}
   void* operator new(size_t){
      if(freelist==NULL)
         return ::new Link;
      Link<E>* temp=freelist;
      freelist=freelist->next;
      return temp;
   }
   
   void operator delete(void* ptr){
      ((Link<E>*)ptr)->next=freelist;
      freelist=(Link<E>*)ptr;
   }
};

//The freelist head pointer is actually created here
template <typename E>
Link<E>* Link<E>::freelist=NULL;

(4)顺序表和链表的对比:

*顺序表大小固定,当表中元素只有几个时,浪费很多空间。顺序表的空间需求为Ω(n)

*链表大小灵活,只要存在可用的内存空间分配,个数就没有限制。链表的空间需求为Θ(n)

*顺序表对表中的每一个元素都没有浪费空间,而链表需要在每一个结点上附加一个指针。

*对于取出线性表中某个元素这样的按位置随机访问,顺序表会更快一些;而单链表则不能直接访问前面的元素。

*给出指向链表中合适位置的指针后,链表中insert和remove函数所需要的时间仅用Θ(1),而顺序表则为Θ(n)

*一般规律:当线性表元素数目变化较大或者未知时,最好使用链表实现;而如果用户事先知道线性表的大致长度,使用顺序表的空间效率会更高





  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值