北邮数据结构实验报告 单链表

时间:2024.3.19

北京邮电大学

数据结构试验报告

实验名称:实验一  线性表

学生姓名:

    级:

班内序号

    号:

    期:20##年1月3日

 

1 实验目的

Ø  熟悉C++语言的基本编程方法,掌握集成编译环境的调试方法

Ø  学习指针、模板类、异常处理的使用

Ø  掌握线性表的操作的实现方法

Ø  学习使用线性表解决实际问题的能力

2 实验内容

2.1题目1

根据线性表的抽象数据类型的定义,选择下面任一种链式结构实现线性表,并完成线性表的基本功能。

线性表存储结构(五选一):

1、  带头结点的单链表

2、  不带头结点的单链表

3、  循环链表

4、  双链表

5、  静态链表

    线性表的基本功能:

1、  构造:使用头插法、尾插法两种方法

2、  插入:要求建立的链表按照关键字从小到大有序

3、  删除

4、  查找

5、  获取链表长度

6、  销毁

7、  其他:可自行定义

编写测试main()函数测试线性表的正确性。

3 程序分析

3.1 存储结构

单链表的存储结构:

3.2 关键算法分析

一、关键算法

1.头插法

自然语言描述:a.在堆中建立新结点

            b.将a[i]写入到新结点的数据域

            c.修改新结点的指针域

            d.修改头结点的指针域,将新结点加入链表中

代码描述:

template<class T>

LinkList<T>::LinkList(T a[], int n)//头插法建立

{

       front = new Node<T>;

       front->next = NULL;

       for(int i=n-1;i>=0;i--)

       {

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

              s->data = a[i];

              s->next = front->next;

              front->next = s;

       }

}

时间复杂度:O(n)

2.尾插法

自然语言描述:a.在堆中建立新结点 

              b.将a[i]写入到新结点的数据域

              c.将新结点加入到链表中 

              d.修改修改尾指针

代码描述:

template<class T>

LinkList<T>::LinkList(T a[], int n)//尾插法建立

{

       front = new Node<T>;

       front->next=NULL;

       Node<T> * r = front;

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

       {

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

              s->data = a[i];

              s->next = r->next;

              r->next= s;

              r=s;

       }

}

时间复杂度:O(n)

3.析构函数

自然语言描述:a.新建立一个指针,指向头结点 

              b.移动a中建立的指针

              c.逐个释放指针 

代码描述:

template<class T>

LinkList<T>::~LinkList()//析构函数,销毁链表

{

       Node<T> * p = front;

       while(p)

       {

              front = p;

              p = p->next;

              delete front;

       }

}

4.按位查找函数       

自然语言描述: a.初始化工作指针p和计数器j,p指向第一个结点,j=1

             b.循环以下操作,直到p为空或者j等于1    

               b1:p指向下一个结点    

               b2:j加1

             c.若p为空,说明第i个元素不存在,抛出异常

             d.否则,说明p指向的元素就是所查找的元素,返回元素地址       

代码描述:

template<class T>

Node<T>* LinkList<T>::Get(int i)//按位查找

{

       Node<T> * p = front;

       int j=0;

       while(p)

       {

              if(j<i)

              {

                     p = p->next;

                 j++;

              }

              else break;

       }

       if(!p) throw"查找位置非法";

       else   return p;

}

时间复杂度:O(n)

5.按值查找函数       

自然语言描述:a.初始化工作指针p和计数器j,p指向第一个结点,j=1

              b.循环以下操作,找到这个元素或者p指向最后一个结点

              b1.判断p指向的结点是不是要查找的值,如果是,返回j;

              b2.否则p指向下一个结点,并且j的值加一

              c.如果找到最后一个结点还没有找到要查找的元素,返回查找失败信息        代码描述:

template<class T>

int LinkList<T>::Locate(T x)//按值查找

{

       Node<T> * p = front->next;

       int j = 1;

       while(p)

       {

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

              else

              {

                     p = p->next;

                  j++;

              }

       }

       return -1;

}

时间复杂度:O(n)

6.插入函数

自然语言描述: a.在堆中建立新结点

               b.将要插入的结点的数据写入到新结点的数据域

               c.修改新结点的指针域

               d.修改前一个指针的指针域,使其指向新插入的结点的位置

代码描述:

template<class T>

void LinkList<T>::Insert(int i,T x)//插入函数

{

       Node<T> * p = Get(i-1);

       if(p)

       {

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

              s->data = x;

              s->next = p->next;

              p->next = s;

       }

       else throw"插入位置非法";

}

时间复杂度:O(n)

7.按位删除函数

自然语言描述:a.从第一个结点开始,查找要删除的位数i前一个位置i-1的结点

             b.设q指向第i个元素

             c.将q元素从链表中删除

             d.保存q元素的数据

             e.释放q元素

代码描述:

template<class T>

T LinkList<T>::Delete(int i)//删除函数

{

       Node<T> *p = Get(i-1);

       Node<T> *q = p->next;

    T x=q->data;

       p->next = q->next;

       delete q;

       return x;

}

8.遍历打印函数

自然语言描述: a.判断该链表是否为空链表,如果是,报错

             b.如果不是空链表,新建立一个temp指针 

             c.将temp指针指向头结点

             d.打印temp指针的data域

             e.逐个往后移动temp指针,直到temp指针的指向的指针的next域为空       

代码描述:

template<class T>

void LinkList<T>::PrintList()//打印链表

{

       Node<T> * p = front->next;

       while(p)

       {

              cout<<p->data<<' ';

              p = p->next;  

       }

       cout<<endl;

}

9.获取链表长度函数       

自然语言描述: a.判断该链表是否为空链表,如果是,输出长度0

               b.如果不是空链表,新建立一个temp指针,初始化整形数n为0  

               c.将temp指针指向头结点

               d.判断temp指针指向的结点的next域是否为空,如果不是,n加一,否则return n

               e.使temp指针逐个后移,重复d操作,直到temp指针指向的结点的next域为0,返回n

代码描述:

template<class T>

int LinkList<T>::GetLength()//分析链表长度

{

       Node<T> * p = front;

       int i=0;

       while(p)

       {

              p = p->next;

              i++;

       }

       return i-1;

}

4 程序运行结果

4.1主函数流程图

4.2程序运行框图

5 实验心得

1.调试时出现的问题及解决的方法

    在编写按值查找函数时,由于没有处理好指针类型的原因,导致指针无法正常返回,屡屡报错。最后意识到c++没有指针强制类型的转换机制,经过细致检查后才改正错误使得程序正常运行。

2.心得体会

了解了单链表的基本的操作函数实现,对链式存储结构有了较好的认识

3.下一步的改进

可以增加完善报错机制,增强程序的健壮性

完整源代码

#include<iostream>

using namespace std;

template<class T>

struct Node

{

         T data;

         Node<T> * next;

};

template<class T>

class LinkList

{

public:

         LinkList() { front = new Node<T>; front->next = NULL;}//无参构造函数

         LinkList(T a[],int n);//构造函数

         void Insert(int i,T x);//插入函数

         T Delete(int i);//删除函数

         Node<T>* Get(int i);//查找第几个的元素,返回的是该元素的地址

         int Locate(T x);//定位某元素

         int GetLength();//分析链表长度

         ~LinkList();//析构函数

         void PrintList();//打印链表

private:

         Node<T> * front;

};

//template<class T>

//LinkList<T>::LinkList(T a[], int n)//头插法建立

//{

//       front = new Node<T>;

//       front->next = NULL;

//       for(int i=n-1;i>=0;i--)

//       {

//                Node<T>* s = new Node<T>;

//                s->data = a[i];

//                s->next = front->next;

//                front->next = s;

//       }

//}

template<class T>

LinkList<T>::LinkList(T a[], int n)//尾插法建立

{

         front = new Node<T>;

         front->next=NULL;

         Node<T> * r = front;

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

         {

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

                  s->data = a[i];

                  s->next = r->next;

                  r->next= s;

                  r=s;

         }

}

template<class T>

LinkList<T>::~LinkList()//析构函数,销毁链表

{

         Node<T> * p = front;

         while(p)

         {

                  front = p;

                  p = p->next;

                  delete front;

         }

}

template<class T>

void LinkList<T>::PrintList()//打印链表

{

         Node<T> * p = front->next;

         while(p)

         {

                  cout<<p->data<<' ';

                  p = p->next;       

         }

         cout<<endl;

}

template<class T>

Node<T>* LinkList<T>::Get(int i)//按位查找

{

         Node<T> * p = front;

         int j=0;

         while(p)

         {

                  if(j<i)

                  {

                           p = p->next;

                       j++;

                  }

                  else break;

         }

         if(!p) throw"查找位置非法";

         else   return p;

}

template<class T>

int LinkList<T>::Locate(T x)//按值查找

{

         Node<T> * p = front->next;

         int j = 1;

         while(p)

         {

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

                  else

                  {

                           p = p->next;

                      j++;

                  }

         }

         return -1;

}

template<class T>

void LinkList<T>::Insert(int i,T x)//插入函数

{

         Node<T> * p = Get(i-1);

         if(p)

         {

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

                  s->data = x;

                  s->next = p->next;

                  p->next = s;

         }

         else throw"插入位置非法";

}

template<class T>

T LinkList<T>::Delete(int i)//删除函数

{

         Node<T> *p = Get(i-1);

         Node<T> *q = p->next;

    T x=q->data;

         p->next = q->next;

         delete q;

         return x;

}

template<class T>

int LinkList<T>::GetLength()//分析链表长度

{

         Node<T> * p = front;

         int i=0;

         while(p)

         {

                  p = p->next;

                  i++;

         }

         return i-1;

}

void main()

{

         int n;

         cout<<"将要输入的链表长度为:";

         cin>>n;

         int *b=new int[n];

         cout<<"输入链表中的元素:";

         for(int k=0;k<n;k++) cin>>b[k];

         LinkList<int> a(b,n);

         a.PrintList();

         cout<<"链表的长度:"<<a.GetLength()<<endl;

         int i;

         cout<<"请输入要删除元素的位置:";

         cin>>i;

         cout<<"被删除掉的元素是:"<<a.Delete(i)<<endl;

         cout<<"删除后得到的链表是:";

         a.PrintList();

         int j;

         cout<<"请输入要插入的元素:";

         cin>>j;

         cout<<"要将其插入在哪个位置:";

         cin>>i;

         a.Insert(i,j);

         cout<<"插入后得到的链表是:";

         a.PrintList();

         cout<<"要查找第几个元素:";

         cin>>i;

         cout<<"要查找的元素为:"<<a.Get(i)->data<<endl;

         cout<<"要探寻位置的元素大小为:";

         cin>>j;

         cout<<"输入的元素位置在:"<<a.Locate(j)<<endl;

}

更多相关推荐:
数据结构单链表实验报告

一设计人员相关信息1设计者姓名学号和班号12地信李晓婧120xx2429832设计日期20xx3上机环境VC60二程序设计相关信息1实验题目编写一个程序实现单链表的各种基本运算假设单链表的元素类型为char并在...

数据结构课程单链表实验报告

数据结构实验报告郑州轻工业学院数据结构课程实验实验报告题目单链表表的基本操作及c语言实现专业信息管理与信息系统班级1101姓名高博文完成日期郑州轻工业学院数据结构实验报告一试验内容用c语言实现单链表的建立插入删...

数据结构单链表实验报告

数据结构课程实验报告注空间不够可以增加页码

数据结构单链表实验报告1

实验报告实验课程实验项目专业姓名学号实验时间计算机科学与技术学院算法基本思想11链表中插入元素申请内存后将读入的元素存入并加入到尾节点的指针域中利用循环遍历来查找尾节点2而顺序表则直接向数组中插入时间复杂度Tn...

数据结构单链表插入、删除和修改实验报告

计算机学院实验报告课程名称实验名称单链表学生姓名学生学号20xx0511001实验日期20xx1一实验目的1理解数据结构中带头结点单链表的定义和逻辑图表示方法2掌握单链表中结点结构的C描述3熟练掌握单链表的插入...

数据结构单链表操作验证实验报告

班级计算机112学号40姓名朱报龙成绩实验三单链表操作验证一实验目的掌握线性表的链接存储结构验证单链表及其基本操作的实现进一步掌握数据结构及算法的程序实现的基本方法二实验内容用头插法或尾插法建立带头结点的单链表...

数据结构实验报告一(链表)

数据结构实验报告一20xx5182刘宗明信息管理与信息系统093班一实验目的1理解线性表的链式存储结构2熟练掌握动态链表结构及有关算法的设计3根据具体问题的需要设计出合理的表示数据的链表结构并设计相关算法二实验...

数据结构实验报告

数据结构实验报告专业班级142姓名王金涛学号学期指导老师成绩教师评语学号1408090204姓名王金涛所在系信息学院班级惠普测试142实验名称线性结构基本算法的实现实验日期实验指导教师刘勇实验机房1实验目的1掌...

数据结构实验报告册

软件学院上机实验报告第一次实验实验题目单链表实验要求1掌握单链表基本结构定义2实现基本操作3熟悉单链表操作特点实验内容1线性表的抽象数据类型定义2单链表存储结构的C语言定义3实现基本操作a初始化b销毁c取数据元...

数据结构上机报告:编写一个程序,实现单链表的各种基本运算

数据结构上机报告月姓名学号同组成员无1实验题目及要求编写一个程序实现单链表的各种基本运算2需求分析建立一个单链表实现单链表的初始化插入删除节点等功能以及确定某一元素在单链表中的位置1初始化单链表2依次采用尾插入...

数据结构实验报告_合并链表

数据结构链表合并实验报告一需求分析1输入的形式和输入值的范围根据题目要求与提示输入两链表且数与数之间用空格隔开输入一行数后用0作为结束符2输出的形式输出合并后的链表3程序所能达到的功能程序能合并两个有序链表为一...

数据结构链表的插入和删除实验报告

第三次实验报告单链表的建链表插入结点删除结点运算一需求分析1在演示程序中出现的元素以数字出现2演示程序在计算机终端上用户在键盘上输入演示程序中规定的运算命令相应的输入数据和运算结果显示在终端上3程序执行的命令包...

数据结构单链表实验报告(35篇)