第二章 线性表

来源:互联网 发布:周末可以做的兼职知乎 编辑:程序博客网 时间:2024/06/16 04:25

       第二章  线性表

一.线性表的逻辑结构

1.线性表:简称表,是nn>=0)个具有相同类型的数据结构的有限序列。

2.线性表的长度:线性表中数据元素的个数。

3.线性表中的元素,除第一个数据元素无前驱,最后一个数据元素无后继外,其他数据元素都有前驱和后继。

4.线性表的抽象数据类型定义:

(1)Initlist:(无输入输出)功能:线性表的初始化。

(2)Destroylist:(无输入输出)功能:销毁线性表。

(3)Length:(无输入有输出)功能:求线性表的长度。注:输出为线性表中数据元素的个数。

(4)Get:(有输入输出)功能:按位查找,在线性表中查找序号为i的数据元素。

注:输入为元素的序号i;输出为在序号合法的情况下序号为i的元素值,否则抛出异常。

(5)Locate:(输入:数据元素x输出:如果查找成功,返回元素x在表中的序号,否则返回0)功能:插入操作,在线性表的第i个位置处插入一个新元素x

(6)Delete:(输入:删除位置i输出:若删除成功,返回被删元素,否则抛出异常)

功能:删除操作,删除线性表的第i个元素。

(7)Printlist:(输入:无;输出:线性表的各个数据元素)功能:遍历操作,按序号依次输出线性表中的元素。

(8)Empty:(输入:无;输出:若是空表返回1,否则返回0)功能:判空操作,判断线性表是否为空表。

注:上述八条为线性表的基本操作。

二.线性表的顺序存储结构及实现

1.线性表的顺序存储结构——顺序表

注:顺序表是用一段地址连续的存储单元依次存储线性表的数据元素。

2.循序表的模板:

 const int maxsize=10;

template<class dt>

class seqlist

{

public:

     seqlist(){length=0;}

     seqlist(int a[],int n);

     ~seqlist(){}

     void Insert(int i,int x);

     int Delete(int i);

     int Locate(int x);

     void Printlist();

private:

     int data[maxsize];

     int length;

};

(1)参构造函数seqlist

template<class dt>

   seqlist::seqlist(int a[],int n)

{

     if(n>maxsize)throw "非法参数";

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

            data[i]=a[i];

     length=n;

}

(2)按位查找算法Get

template<class dt>

dt seqlist<dt>::Get(int i)

{

if (i<1||i>length)throw“查找位置非法”

else return data[i-1];

}

(3)按值查找算法Locate

template<class dt>

   int seqlist::Locate(int x)

{

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

            if(data[i]==x) return i+1;

            return 0;

}

(4)插入算法Insert

template<class dt>

void seqlist::Insert (int i,int x)

{

     if(length>=maxsize)throw"上溢";

     if(i<1||i>length+1)throw"位置非法";

     for(int j=length;j>=i;j--)

            data[j]=data[j-1];

     data[i-1]=x;

     length++;

}

(5)删除算法Delete

template<class dt>

int seqlist::Delete(int i)

{

     if(length==0) throw "下溢";

     if(i<1||i>length) throw"位置非法";

     int x=data[i-1];

     for(int j=i;j<length;j++)

            data[j-1]=data[j];

     length--;

     return x;

}

(6)遍历算法Printlist

template<class dt>

void seqlist::Printlist()

{

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

            cout<<data[i]<<"  ";

     cout<<endl;

}

三.线性表的链接存储结构及实现

1.单链表:用一组任意的存储单元存放线性表的元素,这组存储单元可以联系也可以不连续,甚至可以零散分布在内存中的任意位置。

2.每个存储单元在存储数据元素的同时,还必须存储其后继元素所在的地址信息,这个地址信息称为指针这两部分组成了数据元素的存储映像,称为节点

注:节点中的数据部分用p->data标识,地址部分用p->next标识。

3.单链表的模板:

template <class dt>

struct Node

{

     dt data;

     Node<dt>*next;

};

template<class dt>

class linklist

{

     public:

            linklist();

            linklist(dt a[],int n);

            ~linklist();

            int Locate(dt x);

            void Insert(int i,dt x);

            dt Delete(int i);

            void Printlist();

     private:

         Node<dt>*first;

}

(1)遍历算法Printlist

template<class dt>

void linklist<dt>::Printlist()

{

     Node<dt>*p=first->next;

     while(p!=NULL)

     {

            cout<<p->data<<" ";

            p=p->next;

     }

     cout<<endl;

}

(2)长度算法Length

template<class dt>

int linklist<dt>::Length()

{

p=first->next;count =0;

while(p!=NULL)

{

p=p->next;

count ++;

}

return count;

}

(2)按位查找算法Get

template<class dt>

dt linklist<dt>::Get(int i)

{

p=first->next;count=1;

while(p!=NULL&&count<i)

{

p=p->next;count ++;

}

if(p==NULL)throw”位置”;

else return p->data;

}

(3)按值查找算法Locate

template<class dt>

int linklist<dt>::Locate(dt x)

{

     Node<dt>*p=first->next;

     int count=1;

     while(p!=NULL)

     {

            if(p->data==x)return count;

            p=p->next;

            count++;

     }

     return 0;

}

(4)插入算法Insert

template<class dt>

void linklist<dt>::Insert(int i,dt x)

{

     Node<dt>*p=first,*s=NULL;

     int count=0;

     while(p!=NULL&&count<i-1)

     {

            p=p->next;

            count++;

     }

     if(p==NULL) throw"位置";

     else {

            s=new Node<dt>;s->data=x;

            s->next=p->next;p->next=s;

     }

}

(5)无参构造函数linklist

template<class dt>

linklist<dt>::linklist()

{

first=new Node;

first->next=NULL;

}

(6)头插法建立单链表linklist

template<class dt>

linklist<dt>::linklist(dt a[n],int n)

{

first=new Node;first->next=NULL;

for(i=0;i<n;i++)

{

s=new Node;s->data=[i];

s->next=first->next;first->next=s;

}

}

(7)尾插法建立单链表linklist

template<class dt>

linklist<dt>::linklist(dt a[n],int n)

{

first=new Node;r=first;

for(i=0;i<n;i++)

{

s=new Node;s->data=a[i];r->next=s;r=s;

}

r->next=NULL;

}

(8)删除算法Delete

template<class dt>

dt linklist<dt>::Delete(int i)

{

     Node<dt>*p=first,*q=NULL;

     dt x;

     int count=0;

     while(p!=NULL&&count<i-1)

     {

            p=p->next;

            count++;

     }

     if(p==NULL||p->next==NULL)

            throw"位置";

     else{

            q=p->next;x=q->data;

            p->next=q->next;

            delete q;

            return x;

     }

}

(9)析构函数算法~linklist

template<class dt>

linklist<dt>::~linklist()

{

whilefirst!=NULL

{

q=first;first=first->next;

Delete q;

}

}

4.双链表的实现实例:

1.新建一个空工程,命名为“循环链表验证试验”,在该工程中新建一个头文件dullist.h该头文件包括顺序表类 dullist 的定义。如下图:

 

#ifndef dullist_H

#define dullist_H

 

template <class dt>

struct DulNode

{

      dt data;

      DulNode<dt>*prior,*next;

};

template<class dt>

class dullist

{

      public:

             dullist();

             dullist(dt a[],int n);

             ~dullist();

             int Locate(dt x);

             void Insert(int i,dt x);

             dt Delete(int i);

             void Printlist();

      private:

             DulNode<dt>*first;

};

#endif

2.在工程“循环列表验证试验”中新建一个源程序文件 dullist.cpp ,该文件包括类 dullist中程序函数的定义,如下图:

#include<iostream>

using namespace std;

#include"dullist.h"

template<class dt>

dullist<dt>::dullist()

{

      first=new DulNode<dt>;

      first->next=NULL;

}

template<class dt>

dullist<dt>::dullist(dt a[],int n)

{

      DulNode<dt>*r,*s;

      first=new DulNode<dt>;

      r=first;

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

      {

             s=new DulNode<dt>;

             s->data=a[i];s->prior=r;

             r->next=s;r=s;

      }

      r->next=NULL;

}

template<class dt>

dullist<dt>::~dullist()

{

      DulNode<dt>*q=NULL;

      while(first!=NULL)

      {

             q=first;

             first=first->next;

             delete q;

      }

}

template<class dt>

void dullist<dt>::Insert(int i,dt x)

{

      DulNode<dt>*p=first,*s=NULL;

      int count=0;

      while(p!=NULL&&count<i-1)

      {

             p=p->next;

             count++;

      }

      if(p==NULL) throw"位置";

      else {

             s=new DulNode<dt>;s->data=x;

             s->next=p->next;p->next->prior=s;

             p->next=s;

      }

}

template<class dt>

dt dullist<dt>::Delete(int i)

{

      DulNode<dt>*p=first;

      dt x;

      int count=0;

      while(p!=NULL&&count<i-1)

      {

             p=p->next;

             count++;

      }

      if(p==NULL||p->next==NULL)

             throw"位置";

      else{

             x=p->data;

            

             (p->prior)->next=p->next;

             (p->next)->prior=p->prior;

             delete    p;

             return x;

      }

}

template<class dt>

int dullist<dt>::Locate(dt x)

{

      DulNode<dt>*p=first->next;

      int count=1;

      while(p!=NULL)

      {

             if(p->data==x)return count;

             p=p->next;

             count++;

      }

      return 0;

}

template<class dt>

void dullist<dt>::Printlist()

{

      DulNode<dt>*p=first->next;

      while(p!=NULL)

      {

             cout<<p->data<<" ";

             p=p->next;

      }

      cout<<endl;

}

3.在工程中新建一个源程序文件 cirlist_main.cpp ,如下图:

#include<iostream>

using namespace std;

#include"dullist.cpp"

void main()

{

     int r[5]={1,2,3,4,5};

     dullist<int>L(r,5);

     cout<<"执行插入操作前数据为:"<<endl;

     L.Printlist();

     try

     {

            L.Insert(2,3);

     }

     catch(char*s)

     {

            cout<<s<<endl;

     }

     cout<<"执行插入操作后数据为:"<<endl;

     L.Printlist();

     cout<<"值为5的元素位置为:";

     cout<<L.Locate(5)<<endl;

   cout<<"执行删除操作前数据为:"<<endl;

     L.Printlist();

     try

     {

     

            L.Delete(2);

     }

           

     catch(char*s)

     {

            cout<<s<<endl;

     }

     cout<<"执行删除操作后数据为:"<<endl;

     L.Printlist();

}

0 0