中国矿业大学 空间数据结构上机实验报告.docx
- 文档编号:27056575
- 上传时间:2023-06-26
- 格式:DOCX
- 页数:19
- 大小:68.22KB
中国矿业大学 空间数据结构上机实验报告.docx
《中国矿业大学 空间数据结构上机实验报告.docx》由会员分享,可在线阅读,更多相关《中国矿业大学 空间数据结构上机实验报告.docx(19页珍藏版)》请在冰豆网上搜索。
中国矿业大学空间数据结构上机实验报告
《空间数据结构基础》
上机实验报告(2010级)
姓名
班级
学号
环境与测绘学院
1.顺序表的定义与应用(课本P85习题)
【实验目的】
熟练掌握顺序表的定义与应用,通过上机实践加深对顺序表概念的理解。
【实验内容】
设有两个整数类型的顺序表A(有m个元素)和B(有n个元素),其元素均从小到大排列。
试编写一个函数,将这两个顺序表合并成一个顺序表C,要求C的元素也从小到大排列。
【主要代码】
#include
#include
constintdefaultSize=100;
template
classSeqList{
protected:
T*data;//存放数组
intmaxSize;//最大可容纳表象的项数
intLast;//当前已存表象的项数
voidreSize(intnewSize);//改变data数组空间大小
public:
SeqList(intsz=defaultSize);
SeqList(SeqList
~SeqList(){delete[]data;}
intSize()const{returnmaxSize;}
intLength()const{returnLast+1;}
intSearch(T&x)const;
intLocate(inti)const;
TgetData(inti)const;
boolsetData(inti,T&x)
{if(i>0&&i<=Last+1)data[i-1]=x;}
boolInsert(inti,T&x);
boolRemove(inti,T&x);
boolIsEmpty()
{return(Last==-1)?
true:
false;}
boolIsFull()
{return(Last==maxSize-1)?
true:
false;}
voidinput();
voidoutput();
SeqList
friendvoidrank(SeqList
friendvoidhebing(SeqList
};
//构造函数,通过指定参数sz定义数组的长度
template
SeqList
:
SeqList(intsz){
if(sz>0){
maxSize=sz;
Last=-1;
data=newT[maxSize];
if(data==NULL)
{cerr<<"存储分配错误"< (1);} } } //复制构造函数,用参数表中给出的已有顺序表初始化新建的顺序表 template SeqList : SeqList(SeqList maxSize=L.Size(); Last=L.Length()-1; data=newT[maxSize]; if(data==NULL) {cerr<<"存储分配错误"< (1);} for(inti=1;i<=Last+1;i++) data[i-1]=L.getData(i); } //用于取第i个表项的值 template TSeqList : getData(inti)const{ if(i<1||i>Last+1){cerr<<"存储分配错误"< (1);} elsereturndata[i-1]; } //私有函数,扩充顺序表的存储空间大小,新数组的元素个数为newsize template voidSeqList : reSize(intnewSize) { if(newSize<=0) {cerr<<"无效的数组大小"< if(newSize! =maxSize) {T*newarray=newT[newarray]; if(newarray=NULL) {cerr<<"存储分配错误"< (1);} intn=Last+1; T*srcptr=data; T*destptr=newarray; while(n--)*destptr++=*srcptr++; delete[]data; data=newarray;maxSize=newSize; } } //搜索函数 template intSeqList : Search(T&x)const { for(inti=0;i<=Last;i++) if(data[i]==x)returni+1; return0; } //定位函数 template intSeqList : Locate(inti)const{ if(i>=1&&i<=Last+1)returni; elsereturn0; } //插入函数 template boolSeqList : Insert(inti,T&x){ if(Last==maxSize-1)returnfalse; if(i<0||i>Last+1)returnfalse; for(intj=Last;j>=i;j--) data[j]=data[j-1]; data[i]=x; Last++; returntrue; } //删除函数 template boolSeqList : Remove(inti,T&x){ if(Last==-1)returnfalse; if(i<1||i>Last+1)returnfalse; x=data[i-1]; for(intj=i;j<=Last;j++) data[j-1]=data[j]; Last--; returntrue; } //输入函数 template voidSeqList : input(){ cout<<"开始建立顺序表,请输入表中元素的最后位置: "; while (1){ cin>>Last;Last--; if(Last<=maxSize-1)break; cout<<"表元素个数有误,个数不能超过"< "; } for(inti=0;i<=Last;i++) {cin>>data[i];} } //输出函数 template voidSeqList : output(){ cout<<"顺序表中当前元素的最后位置为: "< for(inti=0;i<=Last;i++) cout< } //重载操作,顺序表整体赋值 template SeqList : operator=(SeqList maxSize=L.Size(); Last=L.Length()-1; data=newT[maxSize]; if(data==NULL) {cerr<<"存储分配错误"< (1);} for(inti=1;i<=Last+1;i++) data[i-1]=L.getData(i); } //合并函数,用于合并顺序表LA,LB。 结果存于LA。 重复元素只留一个。 voidhebing(SeqList intn=LA.Length(),m=LB.Length(),k,x; for(inti=1;i<=m;i++) { x=LB.getData(i); k=LA.Search(x); if(k==0) {LA.Insert(n,x);n++;} } } //对合并后的顺序表进行排序 voidrank(SeqList { inti,j,temp; for(i=1;i for(j=0;j { if(L.data[j]>L.data[j+1]) { temp=L.data[j]; L.data[j]=L.data[j+1]; L.data[j+1]=temp; } } } voidmain() { SeqList SeqList LA.input(); LB.input(); hebing(LA,LB); SeqList rank(LC); LC.output(); } 运行结果: 【实验体会】 通过本次试验,我熟练掌握顺序表的定义与应用。 此次实验通过对顺序表的类定义,进行两顺序表的合并,并在合并后删除相同的元素,然后对新数组进行从小到大的排序。 因为顺序表是基于一维数组的储存,所以可以选择冒泡法进行排序。 类代码中包含三个数据成员,多个作为外部接口的成员函数,完成顺序表的搜索,定位,插入和删除等操作。 运用类模板,Seqlist的数据成员不使用固定的类型定义,而是用class说明的虚拟类型名T作为变量的类型,在定义Seqlist类的对象时,再用C++的基本类型将对象的数据成员的类型实例化。 这样做的好处是可以使用同一个类来定义不同数据类型的对象,提高代码的利用率。 本次试验,受益匪浅。 2.单链表的使用(书P86习题) 【实验简介】 学会用算法语言C++描述抽象数据类型,使用模板建立数据结构。 能够使用链表类的定义和部分函数的使用。 掌握其数据结构的构建方式并实现相关成员函数。 【实验内容】 设有一个表头指针为h的单链表。 试设计一个算法,通过遍历一趟链表,将链表中所有结点的链接方向逆转。 要求逆转结果链表的表头指针h指向原链表的最后一个结点。 【主要代码】 #include usingnamespacestd; template structLinkNode{//链表结点类的定义 Tdata;//数据域 LinkNode LinkNode(LinkNode LinkNode(constT&item,LinkNode {data=item;link=ptr;}//将数据成员初始化 }; template classList{//链表类的定义,直接使用链表结点类的操作 protected: LinkNode public: List(){first=newLinkNode List(constT&x){first=newLinkNode voidInputRear(intendTag);//后插法建立单链表函数,以endTag为结束标识符 voidoutput();//用于转置前和转置后链表的输出 voidreverse();//转置函数 }; template voidList : InputRear(intendTag){//后插法建立单链表,保证插入的数的顺序与链表一致 LinkNode cin>>val;last=first; while(val! =endTag){ newnode=newLinkNode if(newnode==NULL){cerr<<"分配内存出错"< (1);} last->link=newnode;last=newnode;//插入到表末端 cin>>val;//再输入下一个数 } last->link=NULL;//表收尾,将最后一个数的link域为NULL }; //下面输出函数是用于输出链表 template voidList : output(){ LinkNode while(current! =NULL){ cout< current=current->link; } } //下面为对链表实现转置的函数 template voidList : reverse(){ //转置函数的实现 LinkNode p=h->link; h->link=NULL; while(p! =NULL) { q=p; p=p->link; q->link=h->link; h->link=q; } } voidmain(){ List cout<<"请输入若干数,以0作为结尾"< L.InputRear(0);//调用后插法建立单链表函数 cout<<"链表转置前为"< L.output();//输出未转置的链表 L.reverse();//调用转置函数,实现转置 cout<<"链表转置后为"< L.output();//输出转置后的链表 } 【实验过程】 首先通过结构体和类建立接点和链表。 然后,分别对实现功能所需要的函数进行定义 然后,对定义的各部分函数,进行具体分布实施。 运行如图: 【实验体会】 通过本次试验,我熟悉并掌握了链表的使用。 链表适用于插入和删除频繁,存储空间需求不定的情形,有效的克服了顺序表的效率低和时间开销大缺点。 带附加头结点的单链表,能够方便的进行链表的插入和删除等各类操作的实现。 建立链表时使用后插法建立,使得链表的物理顺序和逻辑顺序一致,符合人们的使用习惯。 在函数的实现的过程中,采用自顶向下分解的方法。 受益匪浅。 3.队列和栈的相关应用(书P134习题) 【实验简介】 学会用算法语言C++描述抽象数据类型,使用模板建立数据结构。 能够对栈和队列的理解和相关函数的应用。 【实验内容】 设用链表表示一个双端队列,要求可以从表的两端插入,但限制只能在表的一端删,试编写基于此的队列的插入和删除算法,并给出队空的的条件。 【主要代码】 #include usingnamespacestd; template structLinkNode{//链表结点类的定义 Tdata;//数据域 LinkNode LinkNode(LinkNode LinkNode(constT&item,LinkNode {data=item;link=ptr;}//将数据成员初始化 }; template classDeque{//Deque类 protected: LinkNode public: Deque()//Deque的构造函数 {front=rear=newLinkNode voidEnqueue(T&x,intDir);//插入函数,x为插入的数,tag为插入的方向 voidDequeue();//删除函数 boolIsempty(){return(rear==front)? true: false;}//判断是否为空 voidoutput();//输出函数 }; template voidDeque : Enqueue(T&x,intDir){//插入函数的实现 if(Dir==0){//规定tag=0为从前端插入 LinkNode newnode=newLinkNode if(newnode==NULL){cerr<<"分配内存出错"< (1);}//容错处理 newnode->link=front->link;//插入的实现 front->link=newnode; if(rear->link! =NULL)//保证rear指针是指向最后的接点 {rear=rear->link;} } else{//从后端插入 LinkNode newnode=newLinkNode if(newnode==NULL){cerr<<"分配内存出错"< (1);} newnode->link=rear->link; rear->link=newnode; rear=rear->link;//在后端插入 } } template voidDeque : Dequeue(){//删除函数的实现,从后端删除 LinkNode p=front;//从front开始历遍到rear前一个 if(Isempty()==true)//判断链表是否为空 {cout<<"队列为空,无法删除"< (1);}//若空则直接退出 else while(p->link! =rear){p=p->link;}//p指针历遍到rear前一个接点 rear=p; p=p->link; deletep;//删除最后一个接点 rear->link=NULL;//将rear的link域为NULL } template voidDeque : output(){//输出函数的实现 LinkNode current=front->link; while(current! =NULL){ cout< current=current->link; } cout< } voidmain(){ Deque inttemp;//插入的数 intDir;//插入的方向 intcount=1;//计数 while(true){ cout<<"请输入第"< cin>>temp; cout<<"请在输入插入的方向,0代表从前插入,1代表从后面插入"< cin>>Dir; if(temp==0000)//判断是否结束 break; else L.Enqueue(temp,Dir);//插入 count++; } cout<<"插入后链表的数为"< L.output();//调用输出函数 L.Dequeue();//调用删除函数 cout<<"从后端删除后,链表中的数为"< L.output();//输出 } 【实验过程】 首先定义结接点结构体和队列类 插入函数,定义两个指针,并用Dir确定插入的方向,实现从不同方向的输入。 删除函数,仅定义为在队列的末端删除。 定于输出函数,实现函数输出。 运行如图: 【实验体会】 通过本次试验,掌握了双端队列使用方法,并能按照要求,从表的两端插入,在表的一端删除。 此次试验,基于单链表基础上完成的,难度不大。 通过本次试验,熟悉了队列的使用方法,同时巩固了单链表的使用。
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 中国矿业大学 空间数据结构上机实验报告 中国 矿业大学 空间 数据结构 上机 实验 报告