实验3 线性表的链式存储

时间:2024.4.27

实验报告三   线性表的链式存储

班级: 2010251  姓名: 李鑫    学号: 20103277   专业: 信息安全       

一、   实验目的:

(1)  掌握单链表的基本操作的实现方法。

(2)  掌握循环单链表的基本操作实现。

(3)  掌握两有序链表的归并操作算法。

二、   实验内容:(请采用模板类及模板函数实现)

1、线性表链式存储结构及基本操作算法实现

[实现提示]  (同时可参见教材p64-p73页的ADT描述及算法实现及ppt)函数、类名称等可自定义,部分变量请加上学号后3位。也可自行对类中所定义的操作进行扩展。

所加载的库函数或常量定义:

(1)  单链表存储结构类的定义:

//文件包含在LinList.h中

template <class datatype>

class LinkList;

template <class datatype>

class Node

{

    friend class LinkList<datatype>;

    private:

       Node<datatype> *next;

       datatype data;

};

template <class datatype>

class LinkList

{

    public:

       LinkList();//建立只有头结点的空链表

       LinkList(datatype a[],int n);//建立有n个元素的单链表

       ~LinkList(){};//析构函数,释放整个链表空间

       int Length();//求单链表的长度

       datatype Get(int i);//取单链表中第i个结点的元素值

       int Location(datatype x);//求单链表中值为x的元素序号

       void Insert(int i,datatype x);//在单链表中第i个位置插入元素值为x的结点

       datatype Delete(int i);//在单链表中删除第i个结点

       void PrintList();//遍历单链表,按序号依次输出各元素


       bool IsEmpty();//是否为空,空返回1,否则返回0

       void DeleteAll();//删除所有的元素

    private:

       Node<datatype> *head;//单链表的头指针

};

(2)初始化带头结点空单链表构造函数实现

输入:无

前置条件:无

动作:初始化一个带头结点的空链表

输出:无

后置条件:头指针指向头结点。

template <class datatype>

LinkList<datatype>::LinkList()

{

    head=new Node<datatype>;

    head->next=NULL;

}

(3)利用数组初始化带头结点的单链表构造函数实现

输入:已存储数据的数组及数组中元素的个数

前置条件:无

动作:利用头插或尾插法创建带头结点的单链表

输出:无

后置条件:头指针指向头结点,且数组中的元素为链表中各结点的数据成员。

template <class datatype>

LinkList<datatype>::LinkList(datatype a[],int n)

{

    head=new Node<datatype>;

    head->next=NULL;

    Node<datatype> *s;

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

    {

       s=new Node<datatype>;

s->data=a[i];

       s->next=head->next;

       head->next=s;

    }

}

(4)在带头结点单链表的第i个位置前插入元素e算法

输入:插入位置i,待插入元素e

前置条件:i的值要合法

动作:在带头结点的单链表中第i个位置之前插入元素e

输出:无

后置条件:单链表中增加了一个结点

template <class datatype>

void LinkList<datatype>::Insert(int i,datatype x)

{

    Node<datatype> *p=head;int j=0;

    while(p&&j<i)

    {

       p=p->next;

       j++;

    }

    if(!p) throw "i不合法";

    else

    {

       Node<datatype> *s=new Node<datatype>;

       s->data=x;

       s->next=p->next;

       p->next=s;

    }

}

(5)在带头结点单链表中删除第i个元素算法

输入:删除第i个结点,待存放删除结点值变量e

前置条件:单链表不空,i的值要合法

动作:在带头结点的单链表中删除第i个结点,并返回该结点的值(由e传出)。

输出:无

后置条件:单链表中减少了一个结点

template <class datatype>

datatype LinkList<datatype>::Delete(int i)

{

    Node<datatype> *p;

    p=head;int j=0;

    while(p&&j<i-1)

    {

       p=p->next;

       j++;

    }

    if (!p||!p->next)

    {

       throw "i不合法";

    }

    else

    {

       Node<datatype> *q;

       datatype x;

       q=p->next;

       x=q->data;

       p->next=q->next;

       delete q;

       return x;

    }

}

(6)遍历单链表元素算法

输入:无

前置条件:单链表不空

动作:遍历输出单链表中的各元素。

输出:无

后置条件:无

template <class datatype>

void LinkList<datatype>::PrintList()

{

    Node<datatype> *p;

    p=head;

    if (!p->next)

       cout<<"表为空";

    else

    {

       while(p->next)

       {

           p=p->next;

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

       }

    }

/*  Node<datatype> *p=head->next;

    while(p)

    {

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

       p=p->next;

    }*/

}

(7)求单链表表长算法。

输入:无

前置条件:无

动作:求单链表中元素个数。

输出:返回元素个数

后置条件:无

template <class datatype>

int LinkList<datatype>::Length()

{

    Node<datatype> *p;

    int i=0;

    p=head->next;

    while(p)

    {

       i++;

       p=p->next;

    }

    return i;

}

(8)判单链表表空算法

输入:无

前置条件:无

动作:判表是否为空。

输出:为空时返回1,不为空时返回0

后置条件:无

template <class datatype>

bool LinkList<datatype>::IsEmpty()

{

    if (head->next==NULL)  return 1;//if(!head->next)  return 1;

    return 0;

/*  if(this->Length()==0)

    {

       return 1;

    }

*/

}

(9)获得单链表中第i个结点的值算法

输入:无

前置条件:i不空,i合法

动作:找到第i个结点。

输出:返回第i个结点的元素值。

后置条件:无

template <class datatype>

datatype LinkList<datatype>::Get(int i)

{

    Node<datatype> *p=head->next;

    int j=1;

    while(p&&j<i)//为i

    {

       p=p->next;

       j++;

    }

    if(!p)  throw "i不合法";

    else  return p->data; // p->next->data;错误

}

(10)删除链表中所有结点算法(这里不是析构函数,但功能相同)

输入:无

前置条件:单链表存在

动作:清除单链表中所有的结点。

输出:无

后置条件:头指针指向空

template <class datatype>

void LinkList<datatype>::DeleteAll()

{

/*  Node<datatype> *p;

    while(head->next)

    {

       p=head->next;

       head->next=p->next;

       delete p;

    }*/

    Node<datatype> *p,*q;

    p=head;

    while (p)

    {

        q=p;   

        p=p->next; 

        delete q;   

    }

    head->next=NULL;

}

 (11)上机实现以上基本操作,写出main()程序:

参考p72

void main()

{

    int s[]={10,9,8,7,6,5,4,3,2,1};int n=10;

   

    cout<<"构造函数插入元素:"<<endl;

    LinkList<int> mylist1(s,10);

    mylist1.PrintList();

    cout<<endl;

   

    cout<<"删除全部元素后为:"<<endl;

    mylist1.DeleteAll();

    mylist1.PrintList();

    cout<<endl<<"单链表为空(1是,0不是):"<<mylist1.IsEmpty()<<endl;

   

    LinkList<int> mylist;

    cout<<endl<<"非构造函数插入元素:"<<endl;

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

       mylist.Insert(i,s[i]);

    //mylist.Insert(0,10);

    //mylist.Insert(1,9);

    mylist.PrintList();

    cout<<endl;

    cout<<"表长为:"<<mylist.Length()<<endl;

    cout<<"得到第3个元素为:"<<mylist.Get(3)<<endl;

    cout<<"删除第7个元素为:"<<mylist.Delete(7)<<endl;

    cout<<"单链表为:";

    mylist.PrintList();

    cout<<endl;

   

    cout<<"第5个元素后插入99后单链表为:";

    mylist.Insert(5,99);

    cout<<endl;

    mylist.PrintList();

    cout<<endl;

}

粘贴测试数据及运行结果:

2、参考单链表操作定义与实现,自行完成单循环链表的类的定义与相操作操作算法。

(1)利用数组初始化带头结点的单循环链表构造函数实现

输入:已存储数据的数组及数组中元素的个数

前置条件:无

动作:利用头插或尾插法创建带头结点的单循环链表

输出:无

后置条件:头指针指向头结点,且数组中的元素为链表中各结点的数据成员,尾指针指向头结点。

template <class datatype>

class LinkList;

template <class datatype>

class Node

{

    friend class LinkList<datatype>;

    private:

       Node<datatype> *next;

       datatype data;

};

template <class datatype>

class LinkList

{

    public:

       LinkList();//建立只有头结点的空链表

       LinkList(datatype a[],int n);//建立有n个元素的单链表

       ~LinkList(){};//析构函数,释放整个链表空间

       //int Length();//求单链表的长度

       //datatype Get(int i);//取单链表中第i个结点的元素值

       //int Location(datatype x);//求单链表中值为x的元素序号

       void Insert(int i,datatype x);//在单链表中第i个位置插入元素值为x的结点

       datatype Delete(int i);//在单链表中删除第i个结点

       void PrintList();//遍历单链表,按序号依次输出各元素

       //bool IsEmpty();

       //void DeleteAll();

       //void sort();

    private:

       Node<datatype> *head;//单链表的头指针

};

template <class datatype>

LinkList<datatype>::LinkList()

{

    head=new Node<datatype>;

    head->next=head;

}

template <class datatype>

LinkList<datatype>::LinkList(datatype a[],int n)

{

    head=new Node<datatype>;

    head->next=head;

    Node<datatype> *s;

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

    {

       s=new Node<datatype>;

       s->data=a[i];

       s->next=head->next;

       head->next=s;

    }

}

(2)在带头结点单循环链表的第i个位置前插入元素e算法

输入:插入位置i,待插入元素e

前置条件:i的值要合法

动作:在带头结点的单循环链表中第i个位置之前插入元素e

输出:无

后置条件:单循环链表中增加了一个结点

template <class datatype>

void LinkList<datatype>::Insert(int i,datatype x)//1<=i<=n;

{

    Node<datatype> *p=head;int j=0;

    while(p->next!=head&&j<i-1)

    {

       p=p->next;

       j++;

    }

    if(j!=i-1) throw "i不合法";

    else

    {

       Node<datatype> *s=new Node<datatype>;

       s->data=x;

       s->next=p->next;

       p->next=s;

    }

}

(3)在带头结点单循环链表中删除第i个元素算法

输入:删除第i个结点,待存放删除结点值变量e

前置条件:单循环链表不空,i的值要合法

动作:在带头结点的单循环链表中删除第i个结点,并返回该结点的值(由e传出)。

输出:无

后置条件:单循环链表中减少了一个结点

template <class datatype>

datatype LinkList<datatype>::Delete(int i)

{

    Node<datatype> *p;

    p=head;int j=0;

    while(p->next!=head&&j<i-1)

    {

       p=p->next;

       j++;

    }

    if (j!=i-1||p->next==head)

    {

       //cout<<"i不合法";

       throw "i不合法";

    }

    else

    {

       Node<datatype> *q;

       datatype x;

       q=p->next;

       x=q->data;

       p->next=q->next;

       delete q;

       return x;

    }

}

(4)遍历单循环链表元素算法

输入:无

前置条件:单循环链表不空

动作:遍历输出单循环链表中的各元素。

输出:无

后置条件:无

template <class datatype>

void LinkList<datatype>::PrintList()

{

    Node<datatype> *p;

    p=head;

    if (p->next==head)

       cout<<"表为空";

    else

    {

       while(p->next!=head)

       {

           p=p->next;

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

       }

    }

/*  Node<datatype> *p=head->next;

    while(p)

    {

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

       p=p->next;

    }*/

}

(5)上机实现以上基本操作,写出main()程序:

#include <iostream.h>

#include "LinList.h"

void main()

{

    int a[]={1,5,8,2,9,4,3,6,7,10},n=10;

    LinkList<int> mylist(a,10);

    cout<<"循环链表为:"<<endl;

    mylist.PrintList();

    cout<<endl;

    cout<<"在第一个元素前插入20后为:"<<endl;

    mylist.Insert(1,20);

    mylist.PrintList();

    cout<<endl;

    cout<<"在第三个元素前插入30后为:"<<endl;

    mylist.Insert(3,30);

    mylist.PrintList();

    cout<<endl;

    cout<<"删除第一个元素后为:"<<endl;

    mylist.Delete(1);

    mylist.PrintList();

    cout<<endl;

    cout<<"删除最后一个元素后为:"<<endl;

    mylist.Delete(11);

    mylist.PrintList();

    cout<<endl;

}

粘贴测试数据及运行结果:

3、采用链式存储方式,并利用单链表类及类中所定义的算法加以实现线性表La,Lb为非递减的有序线性表,将其归并为新线性表Lc,该线性表仍有序(未考虑相同时删除一重复值)的算法。

模板函数:

#include <iostream.h>

#include <stdlib.h>

#include "LinList.h"

template <class datatype>

void LinkList<datatype>::sort()

{

    Node<datatype> *r=head->next;

    datatype temp;

/*  for (i=0;i<Length();i++)

    {

       Node<datatype> *s=r->next;

       for(j=i+1;j<Length();j++)

       {

           if (r->data>s->data)

           {

              temp=r->data;

              r->data=s->data;

              s->data=temp;

              s=s->next;

           }

           //delete q;

       }

       delete s;

       r=r->next;

    }

    delete r;

*/  while(r)

    {

       Node<datatype> *s=r->next;

       while(s)

       {

           if (r->data>s->data)

           {

              temp=r->data;

              r->data=s->data;

              s->data=temp;

           }

           s=s->next;

       }

       delete s;

       r=r->next;

    }

    delete r;

}

void main()

{

    int La[]={1,5,2,7,6,9,3,8,4,10},n=10;

    int Lb[]={3,55,66,77,1,88,2,44},m=8;

    LinkList<int> mylist1(La,10);

    LinkList<int> mylist2(Lb,8);

    cout<<"La链表为:"<<endl;

    mylist1.PrintList();

    cout<<endl;

    cout<<"Lb链表为:"<<endl;

    mylist2.PrintList();

    cout<<endl;

    cout<<"排序后,La链表为:"<<endl;

    mylist1.sort();

    mylist1.PrintList();

    cout<<endl;

    cout<<"排序后,Lb链表为:"<<endl;

    mylist2.sort();

    mylist2.PrintList();

    cout<<endl;

    cout<<"将Lb链表插入La链表后为:"<<endl;

    for (int i=1;i<mylist2.Length()+1;i++)

       mylist1.Insert(mylist1.Length(),mylist2.Get(i));

    mylist1.PrintList();

    cout<<endl;

    cout<<"Lc链表为:"<<endl;

    mylist1.sort();

    mylist1.PrintList();

    cout<<endl;

}

粘贴测试数据及运行结果:

选做题:

1、按一元多项式ADT的定义,实现相关操作算法:

ADT PNode is

Data

系数(coef)

指数(exp)

指针域(next):指向下一个结点

Operation

暂无

end ADT PNode

ADT Polynomial is

Data

   PNode类型的头指针。

Operation 

  Polynomail

   初始化值:无

  动作:申请头结点,由头指针指向该头结点,并输入m项的系数和指数,建立一元多项式。

  DestroyPolyn

   输入:无

前置条件: 多项式已存在

动作:消毁多项式。

输出:无

后置条件:头指针指向空

  PolyDisplay

   输入:无

前置条件: 多项式已存在,不为空

动作:输出多项式各项系数与指数

输出:无

后置条件:无

AddPoly

输入:另一个待加的多项式

前置条件:一元多项式pa和pb已存在。

动作及后置条件:完成多项式相加运算,(采用pa=pa+pb形式,并销毁一元多项式pb)

输出:无

end ADT Polynomial

2、实现一元多项式的减法,操作描述如下:

SubPoly

输入:待减的多项式pb

前置条件:一元多项式pa和pb已存在。

动作及后置条件:完成多项式减法运算,即:pa=pa-pb,并销毁一元多项式pb。

输出:无

3、参考P74-P79页双向链表的存储结构定义及算法,编程实现双向链表的插入算法和删除算法。

三、   心得体会:(含上机中所遇问题的解决办法,所使用到的编程技巧、创新点及编程的心得)

=与==要区别:=是赋值;==是比较;if(head==NULL)易写为:if(head=NULL)

head->next=NULL;//NULL赋给head->next;

while(p&&j<i)是i还是i-1要在程序里测试,有时是i有时是i-1;要与自己的程序匹配。

throw "i不合法";会得到debug调试错误。如图:

删除所有元素后要加一句: head->next=NULL;

while(p)

    {

       i++;

       p=p->next;

    }

这样的循环要注意,很容易产生无限循环。

更多相关推荐:
数据结构 线性表操作实验报告

数据结构实验报告实验题目线性表的操作实验目的1掌握上机调试线性表的基本方法2掌握线性表的一些基本操作实验内容将两个有序链表合并为一个有序链表一需求分析1实验程序中先创建两个有序链表演示程序以用户和计算机的对话方...

数据结构线性表实验报告

《数据结构》实验报告院系应用科技学院专业电子信息工程姓名##学号10级电信班20##年10月11日1.实验目的1.掌握线性表的基本运算。2.掌握顺序村存储的概念,学会对顺序存储数据结构进行操作。3.加深对顺序存…

线性表的基本操作实验报告

实验一线性表的基本操作实验目的学习掌握线性表的顺序存储结构链式存储结构的设计与操作对顺序表建立插入删除的基本操作对单链表建立插入删除的基本操作算法实验内容1顺序表的实践1建立4个元素的顺序表ssqlist123...

数据结构线性表试验报告

线性表上机实习1实验目的1熟悉将算法转换为程序代码的过程2了解顺序表的逻辑结构特性熟练掌握顺序表存储结构的C语言描述方法3熟练掌握顺序表的基本运算查找插入删除等掌握顺序表的随机存取特性4了解线性表的链式存储结构...

数据结构线性表实验报告

浙江万里学院实验报告专业班级计算机111实验小组第十组实验日期20xx921

线性表实验报告

数据结构实验报告实习题名线性表的基本运算以及多项式的算术运算班级B120xx3姓名陈何渊学号B120xx318日期20xx107顺序表的基本运算一问题描述实现单链表的定义和基本操作实现顺序表的逆置删除表中所有元...

线性表实验报告

福州大学数计学院数据结构上机实验报告验内容名称

数据结构--实验报告 线性表的基本操作

一实验目的二实验内容和要求三源代码1顺序表的代码2单链表的代码四测试结果1顺序表的测试结果2单链表的测试结果五心得体会实验一线性表的基本操作及其应用一实验目的1帮助读者复习C语言程序设计中的知识2熟悉线性表的逻...

线性表的插入和删除实验报告

实验报告姓名班级12南航网络学号

线性表归并实验报告

五实验总结和思考填写收获和体会分析成功或失败的原因收获凡事只要经过了自己的实践才能发现问题后才能想办法去解决它才能有新的收获和启发并获取更多的知识同时只有多写代码才能熟悉它们在不断的练习中去获取经验以后遇到相关...

数据结构实验二试验报告 线性表的基本操作

数据结构试验报告实验二线性表的基本操作专业班级网络工程1002班组长王星20xx100230组员郭坤铭20xx100243张磊20xx10024420xx年3月16日一实验项目目的和要求1掌握线性表的特点2掌握...

实验报告--数据结构--线性表的合并

辽宁工程技术大学上机实验报告附页includequotstdiohquotincludequotstdlibhquotdefineLISTINITSIZE100defineLISTINCREMENT10type...

线性表实验报告(37篇)