C++与数据结构 第一次上机实验——线性表

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

实验一线性表
数据结构(C++语言描述)实验报告
实验一线性表
一、实验目的和要求:
1、掌握线性表顺序存储结构和链式存储结构的基本思想;
2、掌握顺序表和单链表的基本操作。

二、实验原理:
1、线性表的定义:数据之间存在一对一的线性关系的数据结构的称为线性结构,也可
称为线性表。

2、顺序存储结构:用一组连续的存储单元依次存储数据元素,数据元素之间的逻辑关
系是由元素的存储的存储位置来表示的,通常用一维数组来表示。

顺序表的优点:存储密度大、空间利用率高、,无需为表中元素之间的逻辑关系而增加额外的存储空间。

顺序表的缺点:插入和删除操作需要移动大量的元素;表的容量难以确定;造成空间的“碎片”。

在程序设计语言中,通常用一维数组来表示表的存储区域。

假设用data[ListSize]来表示一段顺序表,其中ListSize是一个根据实际问题规模定义的足够大的整数,另外用一个实际变量length来表示当前实际元素的个数,表中的数据从data[0]开始依次存放,表空时length=0.
3、链式存储结构:用一组任意的存储单元存储数据元素,数据元素之间的逻辑关系是
用指针来表示的。

链式存储结构的优点:插入和删除操作方便省时。

链式存储结构的缺点:存储空间的开销大。

链式存储的方法是使用结点构造链。

每个结点分为数据域和指针域两部分组成。

数据域用来存放数据元素,指针域用来存放后继存储单元的地址。

三、实验内容
1、对于给定的单链表L,设计一个算法,删除L中值为x的结点的直接前驱结点。

2、已知两个单链表LA和LB分别表示两个集合,其元素递增排列,设计算法求出LA
和LB的交集C,要求C同样以递增的单链表形式存储。

四、实验设计:
1、(1)伪算法:
建立链表L;
循环搜索数据值为x的前一结点,若已至表尾,且其值不为value,警告,退出程序;否则,重新拉链,将数值为x的结点的前一结点标记,将被标记的结点断开,回收被删除的结点的内存空间,将链表长度减1。

(2)实验代码:
//对给定的链表L,设计一个算法,删除L中值为x的结点的直接前驱结点#include<stdlib.h>
#include<iostream>
using namespace std;
class ListNode //建立结点类
{public:
char data;
ListNode *link;
ListNode(){link=NULL;}
ListNode(int&item,ListNode *next=NULL)
{data=item;
link=next;
}
};
class List //建立链表类
{public:
List(){ListNode *q=new ListNode;first=last=q;}
void Great(List L);
voidInsertL(char zifu);
void Print();
charRemovevalue(char value);
private:
ListNode *first,*last;
int length;
};
void List::Great(List L) //建立链表函数
{
char n;
intl,i;
cout<<"请输入链表的长度:";
cin>>l;
cout<<"请输入数据:";
for(i=1;i<l+1;i++)
{ cin>>n;
L.InsertL(n);}
L.length++;
}
void List::InsertL(char zifu)
{ ListNode *newcode=new ListNode;
newcode->data =zifu;
newcode->link=NULL;
if(first==NULL)
{first=newcode;
last=newcode;
}
else last->link=newcode;
last=newcode;
}
char List ::Removevalue(char value) //该函数实现删除值为x的结点的前一结点
{
ListNode *p=first,*q,*h;
while(p->link!=NULL&&p->link->data!=value) {h=p;p=p->link; }
if(p->link==NULL&&p->data!=value)
return 0;
q=h->link;
h->link = q->link;
delete q;
length --;
return value;
}
void List::Print() //打印链表{
ListNode *p;
p=first->link;
while(p!=NULL)
{cout<<p->data<<" ";
p=p->link;
}
cout<<endl;
}
int main()
{
char value;
List a;
a.Great(a);
cout<<"请输入要删除的的数值;"; cin>>value;
a.Removevalue(value);
a.Print();
system("PAUSE");
}
(3)、运行结果
2、(1)伪算法:
要实现此程序核心问题是寻找集合LA和LB的交集,并将其输出,设计思路:
寻找LA的第i个结点,寻找LB的第j个结点,利用嵌套循环,实现链表LA的每一个结点都和LB的结点进行比较,将相等的元素输出到链表LD中;对链表LD中的元素进行去重,然后将链表中没有重叠的元素存入到链表LC中,将链表LC输出。

(2)程序代码:
#include"stdlib.h"
#include"iostream"
using namespace std;
#include"assert.h"
class List; //List类的预先声明
class ListNode //结点类的定义
{
friend class List;
int data;
ListNode *link;
public:
ListNode(){link=NULL;} //缺省构造函数
ListNode(int&item,ListNode *next=NULL) //带参数的构造函数
{
data=item;
link=next;
}
};
class List //建立链表类
{
public:
List() //建立空的链表
{
ListNode *q=new ListNode;
first=last=q;
}
voidCreat(List L);
void Insert(intnum);
ListNode *Find(inti);
intGetlength();
int Get(inti);
void Print();
private:
ListNode *first,*last;
int length;
};
void List::Creat(List L) //创建一个新链表
{
inti,l,x;
cin>>l;
cout<<"请从小到大输入数据:";
for(i=1;i<l+1;i++)
{
cin>>x;
L.Insert(x);
}
L.length++;
}
void List::Insert(intnum) //将新元素插入到表尾位置
{
ListNode *newnode=new ListNode;
newnode->data=num;
newnode->link=NULL;
if(first==NULL)
{
first=newnode;
last=newnode;
}
else last->link=newnode;
last=newnode;
}
int List::Get(inti) //取出链表中的第i个元素
{
ListNode *p=Find(i);
assert(p&&p!=first);
return p->data;
}
ListNode *List::Find(inti) //寻找链表中第i个结点元素的地址{
if(i<-1) return NULL;
if(i==-1) return first;
ListNode *p=first->link;
int j=0;
while(p!=NULL&&j<i)
{
p=p->link;
j++;
}
return p;
}
int List::Getlength() //获得链表的长度
{
length=0;
ListNode *p=first;
while(p->link!=NULL)
{
p=p->link;
length++;
}
return length;
}
void List::Print() //输出链表
{
ListNode *p;
p=first->link;
while(p!=NULL)
{
cout<<p->data<<" ";
p=p->link;
}
cout<<endl;
}
int main()
{ //输入链表LA和LB的数据
List LA,LB,LC,LD;
cout<<"请输入集合LA的长度:";
LA.Creat(LA);
cout<<"LA的数据为:";
LA.Print();
cout<<"请输入集合LB的长度:";
LB.Creat(LB);
cout<<"LB的数据为:";
LB.Print();
//寻找LA和LB中的相同元素,并将其提取到LC中
intla,lb,ld,ta,tb,td,tdd,tl;
la=LA.Getlength();
lb=LB.Getlength(); //得到链表LA和LB的长度
for(inti=0;i<la;i++)
{
ta=LA.Get(i); //获取链表LA的第i个元素
for(int j=0;j<lb;j++)
{
tb=LB.Get(j); //获取链表LB的第j个元素
if(tb==ta) //利用嵌套循环实现链表LA中第i个元素和链表LB 中所有元素进行比较
{LD.Insert(ta);} //如果相等,将元素提取到LD中
}
}
ld=LD.Getlength();
for(int m=1;m<ld;m++) //将链表LD中的元素去重
{
td=LD.Get(m-1);
tdd=LD.Get(m);
if(tdd!=td)
LC.Insert(td); //将没有重叠的元素存入链表LC中}
tl=LD.Get(ld-1);
LC.Insert(tl);
cout<<"LA与LB的交集LC:";
LC.Print();
system("PAUSE");
}
(3)运行结果:
五、编程心得:
1、实践是学习编程语言必须的经历。

这次实验内容完成的并不顺利,尤其是第二题对
于链表LC的输出的实现,每次总是在运行的时候不能输出。

2、其实在理论学习的时候挺不明白链式存储,经过编程发现data域和pointer域的应
用很方便的实现了链表的很多操作,以上两个程序都让我对于这个有了更深的理解。

3、我觉得就C++本身的编程而言是复杂的,但C++可以解决比C语言更加复杂的问题,
尤其是规模较大的问题,因为C++的类和对象成功的将一些数据相统一。

4、编程的过程中遇到了很多的问题,主要是一些基础的格式问题和将书上模板转换成
具体函数的问题,基本上也解决。

在编程过程中,将前面学过的模板只是重新学习,实现了链表模板的具体化。

相关文档
最新文档