`

数据结构-线性表

阅读更多

一.线性表

1.线性表的概念:由称为元素的数据项组成的一种有限有序(有序指线性表中的每一个元素都有自己的位置)的序列。

注:线性表中的第一个位置是用0来表示。

线性表的C++抽象类声明:

(抽象类:成员函数都被声明为"纯虚的",即在函数方法声明的最后有"=0"的符号。)

         template<class Elem> class List{

                    public:

                                 virtual void clear()=0;

                                 virtual void insert(const Elem& )=0;

                                 virtual void append(const Elem& )=0;

                                 virtual void prev()=0; //求前驱。

                                 virtual void next()=0; //求后继。

                                 virtual bool setPos(int pos)=0;

                                 virtual bool getValue(Elem& ) const=0;

                                 virtual void print() const=0;

            };

2.线性表的两种实现方法:顺序表和链表。

1>顺序表的c++实现

顺序表中有一个数据成员fence,用来存储栅栏(当前位置)的位置,栅栏将表分为左右两个部分。

顺序表AList类继承了线性表抽象类List。

   template<class Elem>class AList:public List<Elem>{

        private:

                    int maxSize;//顺序表的最大长度。

                    int fence;//存储栅栏的位置(即当前位置)的值。

                    int listSize;//顺序表当前的长度。

                    Elem*  listArray;

        public:

                    AList(int size=defaultListSize){

                            maxSize=size;

                            listSize=fence=0;

                            listArray=new Elem[maxSize];

                    }

                   ~AList(){ delete[] listArray;}

                   void clear(){

                            delete[] listArray;

                            listSize=fence=0;

                            listArray=new Elem[maxSize];

                    }

                   bool getValue(Elem& it) const{

                            if(rightLength()==0)  return false;

                            else{  it=listArray[fence]; return true;}

                   }

                   bool find(Elem& k){

                            int it;

                            for(listArray.setStart();listArray.getValue(it);ListArray.next())

                                        if(k==it) return true;

                            return false;

                   }

                   ...

         };

在顺序表中插入和删除平均要移动一半数据,即需要O(n)时间。

 

2>链表:利用指针实现线性表。

链表由一系列称为表的结点类(结点类中包括数据域和指针域)的对象组成。可以按照需要为表中新的元素分配存储空间。(动态的)

 一个链表实现的关键设计是怎样表现栅栏(fence),最合理的选择是用指向左边部分的最后一个元素或者是指向右边部分的第一个元素。一般选择指向左边部分的最后一个元素。

链表依据有没有前驱指针又分为单链表和双链表。

a.单链表:每个结点只有一个指向表中下一结点的指针。

单链表的Link类(结点类)的对象包含一个存储元素值的element域和一个存储表中下一个结点指针的next域。

单链表结点类的定义:

           template<class Elem> class Link{

                   public:

                              Elem element;

                              Link  *next;

                              Link(const Elem& elemval , Link* nextval=null){

                                        element=elemval;

                                        next=nextval;

                              }

                              Link(Link *nextval=null){

                                        next=nextval;

                              }

           };

单链表的实现声明:

          template<class Elem> class LList:public List<Elem>{

                   private:

                               Link<Elem> *head;   //头指针,指向链表中的第一个结点。

                               Link<Elem> *tail;  //尾指针,指向链表中的最后一个结点。

                               Link<Elem> *fence; //指向"栅栏"的位置。 栅栏将链表分为左右两部分。

                               int leftLength;   //fence指针指向结点左边的链表结点的个数。

                               int rightLength;   //fence指针指向结点右边的链表结点的个数。

                   public: 

                               void init(){

                                   fence=tail=head=new Link<Elem>;

                                   leftLenght=rightLength=0;

                               }

                               void setStart(){

                                   fence=head;  rightLenght+=leftLength;   leftLength=0;

                               }

                               void setEnd(){

                                   fence=tail;  leftLength+=rightLength;  rightLength=0;

                               }

                               void next(){

                                  if(tail !=null){  fence=fence->next;  rightLength++;  leftLength--; }

                               }

                               bool getvalue(Elem& it) const{

                                  if(rightLenght()==0)  return false;

                                  it=fence->next->element;  return true;

                               }

                              //向栅栏位置(fence指向的地方,即链表的右部分)插入一个元素。

                               bool insert(const Elem& item){

                                  fence->next=new Link<Elem>( item, fence->next);

                                  if(tail==fence)  tail=tail->next;   rightLength++;  return true;

                               }

                               //向链表的末尾插入一个结点。

                               bool append(const Elem& item){

                                  tail=tail->next=new Link<Elem>( item,null);

                                  rightLength++;  return true;

                               }

                              //删除右部分的第一个元素。

                              bool remove(Elem& it){

                                  if(fence->next==null)  return false;

                                  it=fence->next->element; 

                                  Link<Elem> * Itemp=fence->next;

                                  fence->next=Itemp->next;

                                  if(tail==Itemp)  tail=fence;

                                  delete Itemp;

                                  rightLenght--;

                                  return true;

                                }

                               //向左移动fence指针一个位置。

                               /*在单链表中,没有指向前驱结点的指针,所以要实现prev()方法,需要从表头沿链表移

                                 动,直到找到当前结点。

                                void prev(){

                                   Link<Elem>  *temp=head;

                                   if(fence==head)  return;

                                   while(temp->next!=fence) temp=temp->next;

                                   fence=temp;

                                   leftLength--; 

                                   rightLength++;

                                }

                                .....

                  };                                      

 双链表,可利用空间表,栈,递归,队列,字典,二叉树,查找二叉树,堆,Huffman树,待续。。。

0
0
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics