链表实验报告

时间:2024.5.2

重庆工商大学

《数据结构》   课程实验报告封面

专业班级:___           ___   学  号:__         _____

学生姓名:______     _ ______  实验室:__________________

实验题目:_______      双链表的基本操作方法_______________

指导教师:______      ______  成 绩:__________________

日期:2013_9 月____日       第_ 4_ 周    星期__3_节次____

评分表


                目录  

实验题目   ----------------------------------------------------------------------------------   1

实验目的   ----------------------------------------------------------------------------------   1

实验内容   ----------------------------------------------------------------------------------   1

实验要点与要求   -------------------------------------------------------------------------   1

算法思想   ----------------------------------------------------------------------------------   1

算法描述   ----------------------------------------------------------------------------------   1

算法流程图 ----------------------------------------------------------------------------------   4

实验测试与结果   -------------------------------------------------------------------------   5

总结体会   ----------------------------------------------------------------------------------   5

源代码     ----------------------------------------------------------------------------------   6


实验报告的内容与要求

一、实验题目

      双链表的基本操作

二、实验目的

    了解双链表的结构特点及有关概念,掌握双链表的基本操作算法。

三、实验内容

实现双链表的初始化、销毁、建立、插入、删除和查找等基本操作。

四、实验要点与要求

1.  处理的数据类型即ElemType的类型:

      基本版要求:整型、字符型

      扩展版要求:字符串型(基础较好的同学)

2.  参数类型分别用指针、引用和引用型指针    

五、算法思想

    和顺序表不同的是,链表不需要占用一整块事先分配的固定的内存空间,而是采用动态空间链接的方式进行。在每个存储节点都包含了元素本身的信息(数据域)和元素之间的逻辑联系(指针域),就双链表而言,其指针域包含了前驱指针和后续指针,分别用于指向当前节点的上一个节点和下一个节点,故而,对双链表进行操作的时候,要考虑其前驱指针和后续指针的指向,否则容易引起混乱。在链表的操作中,首先最重要的是定义一个头结点,因为指向头结点的指针唯一标识该链表,本次程序采用了不包含任何数据的头节点定义方式。

六、算法描述及流程图

由于程序的分支较多,需要实现的功能也不尽相同,和顺序表一样,我选择了其中插入数据的分支来具体描述其算法,并比较链表和顺序表的操作上的不同:

do{

                              c=ListLength(L);

                              cout<<"\n请输入您需要插入的节点位置(0<number<="<<c+1<<"):";

                              cin>>number;

                              cout<<"插入的数据:";

             if(number<0||number>l+1){cout<<"输入错误!"<<endl;break;

                              cin>>date;

                              ListInsert(L,number,date);

                              cout<<"\n是否需要继续插入?\n";

                              cout<<"  1.是      0.否"<<endl;

                              cout<<"请选择:";

                              cin>>ctrl;

                           }while(ctrl==1);break;

bool ListInsert(DLinkList *&L,int i,ElemType e)//插入数据

{

      int j=0;

      DLinkList *p=L,*s;

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

      {

            j++;

            p=p->next;

      }

      if(p==NULL)

            return false;

      else{

      s=(DLinkList *)malloc(sizeof(DLinkList));

      s->date=e;

      s->next=p->next;

      if(p->next!=NULL)

            p->next->prior=s;

      p->next=s;

      s->prior=p;

      cout<<"插入成功!"<<endl;

      return true;

      }

}

首先,和顺序表一样的是,整个输入分支采用do-while循环进行控制,以便于我们可以多次输入;分支开始的时候,需要用输入插入的元素的位置,并通过一个if条件句判断用户输入的节点位置是否合法,如果节点位置不合法,则提示错误并提前结束分支,返回主菜单。节点位置合法则提示用户输入需要插入的数据,完成后调用ListInsert函数对链表进行插入,和顺序表不一样的是插入的具体实现方式:在插入之前,分配一个指向空节点的指针s和指向头结点的指针p,用p指针找到插入位置的上一个节点位置,如果找到开始执行插入操作,否则退出。插入开始,把用户输入的数据存储在节点s中,把p节点的后继指针指向的节点赋值给s的后继指针,如果p的next域不是空节点,修改其前驱指针指向s;把p的后继指针指向s,s的前驱指针指向p,则s指向的数据就成功插入到链表之中了。

基本流程图如下:

七、实验数据及实验结果

    由于程序和顺序表一样定义为char类型,故而测试的数据和顺序表一样:输入整型,浮点型,字符型,字符串这几种不同类型的数据后,程序的不同输出结果,并且根据顺序表节点数为正整数的特征,测试了输入浮点数,字符,字符串,负数这几种情况下的输出结果。

    对于插入的数据来说总共测试了以下几种数据测试数据及结果如下:

    对于节点,主要测试了以下几种特殊状态的值

实验数据及结果如下:

   通过对于程序处理异常数据的结果进行分析,我发现和双链表的错误和顺序表一样,都是数据类型的不兼容引起程序崩溃

八、实验总结与体会

程序实现了双链表的基本操作,和顺序表相比较,链表的操作更灵活,没有固定的长度限制,只要内存足够,就可以链接数据。大大提高了程序的灵活性和数据处理能力,但是我也发现,链表的指针指向很容易出错,如果指向不对,就会引起系统混乱出现数据异常或者是编译不通过的情况,这样一来对于逻辑要求又有了更高的要求。

九、源代码

#include<iostream>

#include<malloc.h>

using namespace std;

typedef char ElemType;

typedef struct DNode

{

     ElemType date;//数据域

     struct DNode *prior;  //前驱指针

     struct DNode *next;   //后继指针

}DLinkList;

//函数声明

extern void InitList(DLinkList *&L);//初始化双链表

extern void DestroyList(DLinkList *&L);//销毁双链表

extern int  ListLength(DLinkList *L);//链表求长

extern void DispList(DLinkList *L);//输出链表

extern bool GetElem(DLinkList *L,int i,ElemType &e);//按位置查找

extern int  LocateElem(DLinkList *L,ElemType e);//按元素查找

extern bool ListInsert(DLinkList *&L,int i,ElemType e);//插入数据

extern bool ListDelete(DLinkList *L,int i,ElemType &e);//删除第i个位置的元素

//函数定义

void InitList(DLinkList *&L)//初始化链表

{

      L=(DLinkList *)malloc(sizeof(DLinkList));

      L->next=L->prior=NULL;

      cout<<"新建成功!"<<endl;

}

int  ListLength(DLinkList *L)//链表求长

{

      int i=0;

      DLinkList *p=L->next;

      while(p!=NULL)

      {

            p=p->next;

            i++;

      }

      return i;

}

void DispList(DLinkList *L)//输出链表

{

      DLinkList *p=L->next;

      int c;

      c=ListLength(L);

      if(c==0)cout<<" 链表为空,请插入数据!\n"<<endl;

      else{

      while(p!=NULL)

      {

            cout<<p->date<<" ";

            p=p->next;

      }

      cout<<endl;

      }

}

bool GetElem(DLinkList *L,int i,ElemType &e)//按位置查找

{

      int j=0;

      DLinkList *p=L;

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

      {

            j++;

            p=p->next;

      }

      if(p==NULL)

            return false;

      else

      {

            e=p->date;

            return true;

      }

}

int  LocateElem(DLinkList *L,ElemType e)//按元素师查找

{

      int i=1;

      DLinkList *p=L->next;

      while(p!=NULL && p->date!=e)

      {

            p=p->next;

            i++;

      }

      if(p==NULL)

            return 0;

      else return i;

}

bool ListInsert(DLinkList *&L,int i,ElemType e)//插入数据

{

      int j=0;

      DLinkList *p=L,*s;

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

      {

            j++;

            p=p->next;

      }

      if(p==NULL)

            return false;

      else{

      s=(DLinkList *)malloc(sizeof(DLinkList));

      s->date=e;

      s->next=p->next;

      if(p->next!=NULL)

            p->next->prior=s;

      p->next=s;

      s->prior=p;

      cout<<"插入成功!"<<endl;

      return true;

      }

}

bool ListDelete(DLinkList *L,int i,ElemType &e)//删除第i个元素

{

      int j=0;

      DLinkList *p=L,*s;

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

      {

            j++;

            p=p->next;

      }

      if(p==NULL)

            return false;

      else

      {

            s=p->next;

            if(s==NULL)

                  return false;

            p->next=s->next;

            if(s->next!=NULL)

                  p->next->prior=p;

            free(s);

            cout<<"删除成功!"<<endl;

            return true;

      }

}

//测试函数

int main()

{

      DLinkList *L;

      int choose;//主菜单选择分支

      int number;//存储数据位置

      ElemType date;//储存数据

      int c;//顺序表长度

      int ctrl;//函数继续控制变量

            for(;;)

            {

                  cout<<"          "<<endl;

                  cout<<"                            *-*-*-**-*-*-**-*-*-*"<<endl;

                  cout<<"                            *  欢迎使用双向链表*"<<endl;

                cout<<"                            *    1.新建链表    *"<<endl;

                cout<<"                            *    2.数据插入    *"<<endl;

                cout<<"                            *    3.位置查找    *"<<endl;

                cout<<"                            *    4.元素查找    *"<<endl;

                cout<<"                            *    5.删除数据    *"<<endl;

                cout<<"                            *    6.遍历链表    *"<<endl;

                cout<<"                            *    7.退出程序    *"<<endl;

                  cout<<"                            *-*-*-**-*-*-**-*-*-*"<<endl;

                  cout<<"请选择:";

                  cin>>choose;

                  switch(choose){

                        case 1:InitList(L);break;

                        case 2:

                              do{

                              c=ListLength(L);

                              cout<<"\n请输入您需要插入的节点位置(0<number<="<<c+1<<"):";

                              cin>>number;

                              if(number<0||number>c+1){cout<<"输入错误!"<<endl;break;}

                              cout<<"插入的数据:";

                              cin>>date;

                              ListInsert(L,number,date);

                              cout<<"\n是否需要继续插入?\n";

                              cout<<"  1.是      0.否"<<endl;

                              cout<<"请选择:";

                              cin>>ctrl;

                              }while(ctrl==1);break;

                        case 3:

                              do{

                                    for(;;){

                              cout<<"\n请输入您需要查询的节点:";

                              cin>>number;

                              if(number<=0){cout<<"\n节点不合法!\n";}

                              else break;

                                    }

                              date=GetElem(L,number,date);

                              if(GetElem(L,number,date)&&date!=NULL)

                              cout<<"该节点所在数据是:"<<date<<endl;

                              else cout<<"\n无此节点或节点无数据!\n"<<endl;

                              cout<<"\n是否需要继续查询?\n1.是  0.否"<<endl;

                              cout<<"请选择:";

                              cin>>ctrl;

                              }while(ctrl==1);break;

                        case 4:

                              do{

                              cout<<"\n请输入您需要查询的数据值:";

                              cin>>date;

                              number=LocateElem(L,date);

                              if(LocateElem(L,date)&&number>0)

                              cout<<"该数据所在节点为:"<<number<<endl;

                              else cout<<"\n不存在该数据!\n"<<endl;

                              cout<<"\n是否需要继续查询?\n1.是  0.否"<<endl;

                              cout<<"请选择:";

                              cin>>ctrl;

                              }while(ctrl==1);break;

                        case 5:

                              do{

                              cout<<"\n请选择您需要删除的节点:";

                              cin>>number;

                              ListDelete(L,number,date);

                              cout<<"\n是否继续删除?"<<endl;

                              cout<<" 1.是 0.否 \n请选择:"<<endl;

                              cin>>ctrl;

                              }while(ctrl==1);break;

                        case 6:cout<<"\n双向链表所有数据:";DispList(L);cout<<endl;break;

                        case 7:cout<<"感谢您的使用,再见!\n\n"<<endl;exit(0);

                  }//switch尾

            }//for尾

}//main尾

更多相关推荐:
实验八 实验报告表

实验八实验报告表实验名称学号实验报告表81并行算法和串行算法实验数据表1120xx0421姓名宋丽班级020xx303实验时间1219实验报告表82分布式实验数据表实验报告表83虚拟计算实验数据表

实验报告格式模板-供参考

实验名称:粉体真密度的测定粉体真密度是粉体质量与其真体积之比值,其真体积不包括存在于粉体颗粒内部的封闭空洞。所以,测定粉体的真密度必须采用无孔材料。根据测定介质的不同,粉体真密度的主要测定方法可分为气体容积法和…

实验一 实验报告表

实验一实验报告表实验名称学号姓名班级实验时间实验报告表11图灵机模型中的主要组成部分及作用说明可根据需要加行实验报表12冯诺依曼计算机体系结构的功能描述实验报告表13实验所使用的计算机硬件配置登记表实验报告表1...

实验九 实验报告表

五实验报告学号姓名班级实验时间20xx年11月17日实验报告图像生成与图像处理一填写下载图像的相关数据二查看左侧的图像请填写相应的图像编码三计算机中实际存储的图像可能有数几百万像素为了减少图像存储的空间有一种游...

电子表格实验报告

深圳大学实验报告课程名称计算机基础1实验项目名称电子表格学院传播学院专业指导教师报告人彭可学号20xx080289班级实验时间20xx112实验报告提交时间教务处制4一实验目的了解并熟悉软件excel1掌握工作...

实验报告表格 - 副本

学生实验报告学院统计学院课程名称SAS软件专业班级会统核算姓名学号学生实验报告经管类专业用一实验目的及要求1目的2内容及要求二仪器用具运用系统聚类法进行聚类三实验方法与步骤1现有一个班级的全体学生的数学成绩如下...

实验十四 实验报告表

实验十四实验报告表实验名称数据管理与数据库操作实验报告表141数据库管理系统实验数据表实验报告表142虚拟数据库设计实验报告表143虚拟数据库查询1

打印机的实验报告

实验报告实验名称打印机的操作过程实验仪器实验目的认识和了解打印机的工作原理掌握打印机的使实验步骤一打印机与电脑的数据连接HPLaserjetM1319fMFP用方法首先正确关闭电源把USB借口的两端分别连接在电...

电子表格处理实验报告

深圳大学实验报告课程名称计算机基础项目名称电子表格处理学院材料学院专业指导教师王志强报告人彭琼学号20xx20xx40实验时间20xx118提交时间20xx1123教务处制一实验目的与要求1掌握Excel的基本...

实验4电子表格实验报告

深圳大学实验报告课程名称计算机基础实验项目名称电子表格学院经济学院专业国贸指导教师蔡式东报告人朱秒蓉学号20xx020xx2班级实验时间实验报告提交时间教务处制一实验目的了解并熟悉软件excel1掌握工作表和工...

北理大学计算机实验基础_实验18实验报告表

实验十八实验报告表实验名称学号姓名班级实验时间实验报告表181计算机启动过程病毒攻击实验记录表实验报告表182蠕虫病毒攻击实验结果注未感染填无实验报告表183木马攻击实验结果实验报告表184虚拟防火墙实验结果1...

数据分析实验报告

数据分析课程实验报告学院:理学院专业:信息与计算科学班级:姓名:学号:一、实验题目所做实验属于哪一部分的内容。例如:一元线形回归及其在SPSS中的实现。二、实验目的1、加深对聚类分析原理的理解;2、理解聚类分析…

实验报告表(46篇)