线性表(顺序表与链表)的实现

线性表

一、定义:

l  线性表是由称为元素(element)的数据项组成的一种有限且有序的序列。

l  线性表中不包括任何元素时,称之为空表。当前存储的元素数目称之为线性表的长度(length)。线性表的开始节点称为表头(head),结尾节点称为表尾(tail)。表中元素的值与它的未知之间可以有联系也可以没有联系。

l  线性表的第一个元素使用0来表示的。

l  线性表有两种实现方式:顺序表和链表。

l  ADT:

template <typename E> classList {

public:

           List(){}

           virtual ~List() {}

           virtual void append( E& item) = 0;

           virtual E remove() = 0;

           virtual void insert() = 0;

           virtual void moveToStart() = 0;

           virtual void moveToEnd() = 0;

           virtual void moveToPos(int pos) = 0;

           virtual void prev() = 0;

           virtual void next() = 0;

           virtual int length() = 0;

           virtual int currPos() = 0;

           virtual const E& getValue() const = 0;

};

二、顺序表:

l  AList:

template <typenameE>

class AList :publicList < 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];

                   listArray[curr] = it;

                   listSize++;

         }

         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 append(E& item)             //在末尾添加元素

         {

                   assert(listSize < maxSize,"List capacity exceeded");

                   listArray[listSize++] = item;

         }

         void moveToPos(int pos)        //移动到某一个位置

         {

                   assert((pos >= 0)&& (pos < listSize), "No element");

                   curr = pos;

         }

         E remove()                     //删除某一元素

{

                   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;

         }

         const E& getValue() const        //当前位置的值

         {

                   assert((curr>0) &&(curr < listSize), "No current element");

                   return listArray[curr];

         }

};

 

l  平均来说,插入和删除要移动一半的元素,即需要Θ(n)时间。

三、链表:

l  利用指针实现线性表,链表是动态的,它能够按照需要为表中新的元素分配存储空间。

l  链表是由一系列称为表的节点的对象组成的。

l  节点的定义:

Link:

   template <typename E> class Link {

public:

         Eelement;   //节点的值

         Link*next;   //指向下一个节点

   //构造函数

         Link(constE& elemval, Link* nextval = NULL)

         {

                   element= elemval;

                   next= nextval;

         }

         Link(Link*nextval = NULL) { next = nextval; }

};

l  链表类的定义:

template<typenameE> class LList : public Link < 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()   //打印链表元素

       {

                Link* temp = head->next;

                for (int i = 0; i < cnt; i++)

                {

                          cout <<temp->element << " ";

                          temp = temp->next;

                }

                cout << endl;

       }

       void clear(){ removeall(); init(); }

       void insert(const E& it)

       {

                curr->next = newLink<E>(it, curr->next);

                if (tail == curr) tail =curr->next;

                cnt++;

       }

       void append(const E& it)    //添加链表元素

       {

                tail = tail->next = newLink<E>(it, NULL);

                cnt++;

       }

       const E& getValue() const   //获取值

       {

                assert(curr->next != NULL,"No value");

                returncurr->next->element;

       }

       E remove()             //移除当前节点

       {

                assert(curr->next != NULL,"No Element!");

                E it =curr->next->element;

                Link<E>* ltemp =curr->next;

                curr->nect =curr->next->next;

                delete ltemp;

                cnt--;

                return it;

       }

       void moveToEnd()

       {

                curr = head;

       }

       void moveToStart()

       {

                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) return;

                curr = curr->next;

       }

       int length() const

       {

                return cnt;

       }

       int currPos() const  //当前结点

       {

                Link<E>* temp = head;

                int i = 0;

                while (temp != curr)

                {

                          temp = temp->next;

                          i++;

                }

                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;

       }

};

l  可利用空间表

Link类能管理自己的可利用空间表(freelist),以取代反复调用的new和delete。可利用空间表存放当前那些不用的线性表,从一个链表中删除的结点就可以放到可利用空间表的首端。当需要把一个新元素增加到链表中时,先检查可利用空间表,看看是否有可用的线性表节点。如果有空结点,则从可利用空间表中取走一个结点。只有当可利用空间表为空时,才会调用标准操作符new。

 

l  可利用空间表的实现方法:在Link类实现中增加两个新函数,以替代标准的存储分配和回收管理例程new和delete。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值