空间数据结构基础实验指导书学年度Word文档格式.docx
《空间数据结构基础实验指导书学年度Word文档格式.docx》由会员分享,可在线阅读,更多相关《空间数据结构基础实验指导书学年度Word文档格式.docx(37页珍藏版)》请在冰豆网上搜索。
类的数据成员提供对象属性,成员函数提供操作方法,方法是公共接口,用户通过调用方法实现对属性的访问。
一、C++面向对象程序设计范例
1.二维坐标点point的C++描述
【实验目的】用面向对象的方法定义一个简单的抽象数据结构,本例实验内容为坐标点的数据结构。
学会如何用C++语言描述数据结构和算法,理解将数据集和在此数据集上的操作分开描述的方法。
【数据结构】将坐标点数据结构定义为一个C++类Point,在其内部分别定义数据成员和成员函数。
(1)数据成员:
一个平面直角坐标系中的点有两个属性,它们是x轴上的水平坐标值和y轴上的垂直坐标值。
在Point类中,这两个属性分别由数据成员x和y来表示,定义为double类型的私有数据成员。
(2)操作方法:
定义成员函数,为类的使用者提供服务接口。
先设计允许对点对象进行的操作,再用C++描述实现操作的算法,并定义为类Point的成员函数。
在本例中提供了两个操作:
move()函数将一个Point对象移至另一位置,Show()函数输出Point对象的数据成员值。
两个构造函数,分别用于建立缺省参数的对象和带参数的对象。
【算法提示】缺省构造函数Point()将新建立的坐标点对象初始化为原点位置(0,0)。
带参数的构造函数Point(doublepx,doublepy)允许用户建立对象时指定初始坐标位置。
点对象的移动操作move()函数需要在调用时给出新位置参数。
输出坐标值为无参函数。
以下是平面直角坐标系中的点的类定义,main()函数对类Point的属性和操作进行测试。
【程序1.1】
#include<
iostream.h>
classPoint{//平面直角坐标系中的点
private:
doublex;
//水平坐标值
doubley;
//垂直坐标值
public:
Point(){x=0;
y=0;
}//缺省构造函数
Point(doublepx,doublepy){x=px;
y=py;
}//带参数的构造函数
voidmove(doublemx,doublemy){x=mx;
y=my;
}//移动位置(修改坐标值)
voidShow(){cout<
<
"
x="
x<
'
'
y="
y<
endl;
}//输出坐标值
};
voidmain(){
Pointa,b(12.5,34.8);
//建立两个Point对象
cout<
点a的位置:
;
a.Show();
//输出点a的坐标值
点b的位置:
b.Show();
//输出点b的坐标值
a.move(45.6,57.8);
点a移动后的位置:
}
2.使用模板建立坐标点point的数据结构,直接表示抽象数据类型
【实验目的】将程序1.1数据结构的类型参数化(模板),实现更高层次的数据抽象。
【算法提示】Point的数据成员不使用固定的类型定义,而是用typename说明的虚拟类型名ptType作为变量的类型,在定义Point类的对象时,再用C++的基本类型将对象的数据成员的类型实例化。
这样做的好处是可以使用同一个类来定义不同数据类型的对象,提高代码的利用率。
【程序1.2】
template<
typenameptType>
classPoint{//平面直角坐标系中的点
ptTypex;
//虚拟类型的水平坐标值
ptTypey;
//虚拟类型的垂直坐标值
Point(ptTypepx,ptTypepy){x=px;
voidmove(ptTypemx,ptTypemy){x=mx;
}//移动位置(修改坐标值)
Point<
int>
a(24,36);
//建立整型的Point对象
float>
b(12.5,34.8);
//建立浮点型的Point对象
a.move(25,18);
b.move(45.6,57.8);
点b移动后的位置:
注:
定义模板的关键字typename可以用class代替。
如:
classptType>
classPoint与例中的template<
classPoint具有相同功能。
3.利用Point类定义矩形类Rectangle
【实验目的】了解复合数据结构的描述方法。
矩形是一个包含坐标点的复合数据结构,在C++程序中将坐标点和矩形分别定义为具有继承关系的两个类,即定义矩形类Rectangle为Point的派生类。
使用派生类的形式定义一个数据结构,其主要目的是提高基类的代码利用率,并使派生类的结构得到简化。
基类和派生类的定义体现了C++继承机制的运用,最大程度地提高了数据结构的利用率。
【数据结构】派生的矩形类Rectangle有四个数据成员,其中左下角坐标点x和y由基类Point定义,派生类Rectangle能够继承下来作为自己的数据成员。
为了在派生类的成员函数中自由访问基类定义的数据成员,需要将这些数据成员定义为被保护的(protected)访问权限。
矩形的宽度width和高度height在派生类中定义。
在矩形类中这四个数据成员的访问权限是相同的。
【算法提示】
(1)基类Point定义的成员函数都可以由派生类Rectangle继承,在矩形对象中可以直接使用。
(2)若用一个点对象为新的矩形对象初始化,注意构造函数的写法。
对基类成员的赋值由基类的拷贝构造函数完成,例如利用点对象p3定义的矩形对象rt4,实际上使用了Point类的缺省拷贝构造函数。
如果基类成员初始化比较复杂,如含有内存分配等要求,就需要重新定义基类的拷贝构造函数。
【程序1.3】
classPoint{//二维坐标点类
protected:
doublex,y;
doubleGetx(){returnx;
}//返回坐标点的x值
doubleGety(){returny;
}//返回坐标点的y值
voidMove(doublemx,doublemy){x=mx;
}//移动坐标点的位置
}//输出坐标点的属性值
classRectangle:
publicPoint{//矩形类(Point的派生类,Point对象为矩形左下角的坐标点)
doublewidth,height;
//矩形的宽度和高度
Rectangle(){width=0;
height=0;
x=0;
y=0;
}//缺省构造函数
Rectangle(doublea,doubleb,doublec,doubled):
Point(a,b){//带参数的构造函数
width=c;
height=d;
}
Rectangle(Point&
pn):
Point(pn){//带参数的构造函数,由点pn定义矩形左下角的位置
width=1;
height=1;
doubleArea(){returnwidth*height;
}//求矩形的面积
voidSet(doublea,doubleb){x=a;
y=b;
}//重置矩形的左下角坐标
intPosition(Point&
pt);
//求点pt相对于矩形的位置,返回-1(在矩形内),
//0(在矩形边上)和1(在矩形外)
voidJudge(Point&
//判断点pt相对于矩形的位置,给出提示
voidShow();
//输出矩形的各属性值和面积
intRectangle:
:
Position(Point&
pt){//求点pt相对于矩形的位置
if(pt.Getx()<
x||pt.Getx()>
x+width||pt.Gety()<
y||pt.Gety()>
y+height)return1;
//在矩形外
elseif(pt.Getx()>
x&
&
pt.Getx()<
x+width&
pt.Gety()>
y&
pt.Gety()<
y+height)return-1;
//在矩形内
elsereturn0;
//在矩形边上
voidRectangle:
Judge(Point&
pt){
pt.Show();
Show();
switch(Position(pt)){
case0:
cout<
点在矩形边上"
endl<
break;
case-1:
点在矩形内"
case1:
点在矩形外"
Show(){//输出矩形的各属性值和面积
rx="
\t'
ry="
width="
width<
height="
height<
area="
Area()<
Rectanglert1(0,0,6,8),rt2,rt3(rt1);
//定义Rectangle对象
Pointp1(0,0),p2(6,8),p3(5,7);
//定义Point对象
rt1.Show();
//输出矩形rt1的属性值
rt2.Show();
//输出矩形rt2的属性值
rt1.Set(3,5);
//重置矩形rt1左下角的位置
rt2=rt1;
//rt2复制矩形rt1
点p1和矩形rt3:
rt3.Judge(p1);
//判断点p1相对于矩形rt3的位置
rt3.Set(9,4);
//重置矩形rt3左下角的位置
点p2和矩形rt3:
rt3.Judge(p2);
//判断点p2相对于矩形rt3的位置
由p3定义的矩形rt4:
Rectanglert4(p3);
//由p3定义的矩形rt4
rt4.Show();
4.定义矩形类Rectangle,作为Point的友元类
【实验目的】了解复合数据结构的另一种描述方法。
使用多个独立定义的类描述一个数据结构。
【数据结构】将坐标点和矩形分别定义为两个单独的类。
将二者配合使用。
●坐标点类Point:
定义与程序1.1相同。
●矩形类Rectangle:
定义Point对象作为数据成员。
为了能在矩形的函数中访问Point对象的成员,将Rectangle定义为Point的友元。
提示:
友元的使用对于被引用的类可以省去私有数据成员的访问接口,使程序变得更简洁。
其缺点是破坏了数据对象的封装性,有违数据隐藏的原则。
(1)在此算法中使用了函数重载,如move()函数被多次定义,但各函数的作用域和权限是不同的。
(2)为了使用户的操作更简洁,使用了运算符重载(如算术和关系运算符+=和>
,输出运算符<
),这是实现数据封装的常用技术。
【程序1.4】
friendclassRectangle;
//矩形类是点类的友元
friendostream&
operator<
(ostream&
Rectangle&
);
//重载用于矩形的输出运算符
voidmove(Point&
p){x=p.x;
y=p.y;
}//缺省构造函数
classRectangle{//矩形类
//重载输出运算符
Pointpos;
//矩形左下角的坐标点
Rectangle(){pos.x=0;
pos.y=0;
width=0;
Rectangle(doublexv,doubleyv,doublewv,doublelv){//带参数的构造函数
pos.x=xv;
pos.y=yv;
width=wv;
height=lv;
pt){pos.move(pt);
}//移动矩形的左下角坐标
voidset(doublea,doubleb){width=a;
height=b;
}//重置矩形的宽度和高度
intposition(Point&
//求点pt相对于矩形的位置,返回-1(在矩形内),0(在矩形边上)和1(在矩形外)
voidjudge(Point&
//判断点pt相对于矩形的位置,给出提示
//输出矩形的各属性值
voidoperator+=(Rectanglea);
//重载算术运算符“+=”
intoperator>
(Rectanglea);
//重载关系运算符“>
”
position(Point&
pt){//求点pt相对于矩形的位置
if(pt.x<
pos.x||pt.x>
pos.x+width||pt.y<
pos.y||pt.y>
pos.y+height)return1;
elseif(pt.x>
pos.x&
pt.x<
pos.x+width&
pt.y>
pos.y&
pt.y<
pos.y+height)return-1;
//在矩形边上
judge(Point&
pt){//判断点pt相对于矩形的位置,给出提示
Point:
"
//输出点pt的各属性值
switch(position(pt)){
Show(){//输出矩形的位置、大小和面积
pos.x<
'
pos.y<
operator+=(Rectanglea){//重载运算符“+=”,两矩形的宽度和高度相加
width+=a.width;
height+=a.height;
operator>
(Rectanglea){//重载关系运算符“>
”,比较矩形的面积
if(Area()>
a.Area())return1;
ostream&
out,Rectangle&
rg){//重载运算符<
输出矩形的各属性值
out<
rg.pos.x<
rg.pos.y<
rg.width<
rg.height<
returnout;
//定义Rectangle对象
Pointp(0,0),q(9,4);
矩形rt1:
rt1;
矩形rt2:
rt2;
矩形rt3:
rt3;
rt3.judge(p);
//判断点p相对于矩形rt3的位置
rt3.move(q);
//移动矩形rt3的位置,左下角移至点q处
p.move(8,3);
//移动坐标点p的位置
新的矩形rt2:
rt2.move(p);
rt2.set(5,5);
//重置矩形rt2的宽度和高度
rt2+=rt3;
//两矩形的宽度和高度相加
//输出矩形rt2的位置、大小和面积
if(rt2>
rt3)cout<
矩形rt2比rt3大!
elsecout<
矩形rt3比rt2大!
二、C++面向对象程序设计练习
1.定义三维空间的坐标点TPoint
2.描述三维空间的球TBall,实现其主要操作(如计算体积和表面积,输出空间坐标等)。
第2章线性表
了解线性数据结构,掌握顺序存储和链式存储的两种线性表的建立和使用方法。
一、经典算法和例题
1.顺序表的模板类
【实验目的】本例给出了较完整的顺序表的抽象数据类型定义,通过C++类模板的应用体现了数据抽象原理。
【问题描述】定义一个顺序存储的线性表数据结构,在应用程序(main函数)中建立一个整型的线性表对象,在该表中进行插入、删除、查找和输出等操作。
【数据结构】定义一个顺序存储的线性表类SeqList,数据成员包括表的存储数组,表的最大允许长度,表中最后元素下标等。
定义常用的基本操作。
(1)在表示顺序表的SeqList类定义中,表元素的存储空间是数组data,采用动态内存分配方式。
表的初始化工作由构造函数实现。
(2)顺序表的基本操作以公用接口形式(类的成员函数)提供。
一般顺序表最常用的操作是输出、插入、删除、查找和求表长度等,其中数据量较大的输出操作采用运算符重载的方式来实现,以便用户能以习惯的cout<
形式输出表的全部元素。
程序2.1给出顺序表的C++类声明和部分操作的实现。