大榕树——让我们共成长!
大榕树 myDrs.org
您的位置:大榕树 \ 编程       |  Logo语言   |  Pascal语言   |  信息学奥赛   |  高考保送    |  HTML版本
|  Pascal语言>>算法与技巧>>数据结构-线性表 (二)         本站全文搜索: 友情提示:

数据结构-线性表 (二)
http://www.mydrs.org  5/27/2001  大榕树


线性表的顺序存储结构和基本操作
在计算机内存中如何存放线性表呢?其中最简单和常用的方式是用一组地址边续的的存储单元依次存储线性表的元素。假没线性表的每个元素占用L个存储单元,并以所占的第一个单元的存储地址作为数据元素位置,则线性表中第i+1个数据元素的存储位置loc(ai+1)和i个数据元素的存储位置loc(ai)之间应满足下列关系:
loc(ai+1)=loc(ai)+L
如果loc(ai)=b+(i-1)L
线性表的这种机内表示法称为线性表的顺序存储结构。也就是主元素在计算机内以“物理位相邻“来表示线性表中数据元素之间的关系。每一个数据元素的存储位置都和线性表的起始位置相差一个和数据元素在线性表中的位序成正比的常数(如图2.6)。因此,只要确定了存储线性表的起始位置,线性表中任一数据元素都可以随机存取,所以线性表的顺序存储结构是一种随机存取的存储结构。
在PASCAL语言中可用一给数组描述线性表的顺序存储结构:
const
lmaxsize={线性表可能达的最大长度};
type
lelement={线性表元素的数据类型};
lposition=0..lmaxsize;
list=record
date:array[1..lmaxsize]of lelement;
last:lposition;
end;
kusterrir=(bierrmubdexerrmfubdfaukmiverfkiwmybderfkiw)l
在上述 述中,线性表的顺序存储结构是一个记录类型的结构,其中lelement描述线性表元素的数据类型,数据域data描述了线性表中的数据元素占用的数组空间,数组的第i个分量表示线性表中第i个数据元素的存储映像,数据域last指示最后一个数据元素在数组空间中的位置。此处数据元素的存储位置由数组的下标值(即相对于线性表的起始位置的值)来表示。listerror记录对指定的线性表操作后的情况,分别是“操作无误“,“检索出错“,“找不到“,“上溢出“,“下溢出“。
对于图2.1 学生成绩表,假设最多只有300个学生,用PASCAL语言描述的线性表的顺序存储结构如下:
const
lmaxize=300;
type
lelement=record
name:string[8];
chinese:real;
math:real;
sum:real;
average:real;
end;
lposition=0..lmaxize;
list=record
data:array[1..lmaxize]of lelement;
last:lposition;
end;
{定义线性表为list,它最多能容纳lmaxize个元素,首元素序号为1,尾元素序号为last。从宏观角度,如果只关心元素与元素关系时,我们常常把每个元素称为一个结点。}
listerror=(noerro,indexerro,findfail,overflow,underflow);
var
L:list;
lerro:listerro;
线性表是一个相当灵活的数据结构,它的长度可根据需增加或缩短,即对线性表的数据元系不仅可以进行访问,还可进行插入和删除。为了完成线性表的基本操作,我们常常自定义下列函数或过程,参考算法描述如下:
1.初始化操作过程。
procedure lcreate(var L:list);
{没定一个空的线性表L}
begin
L.last:=0:
Lerro:=noerro;
end;
2.求和度函数。
function llength(var L:list):lposition;
{函数值为给定的线性表L中数据元素的个数,函数值为零表示线性表没有元素}
begin
llengtyh:=L.last:
end;
3.判空表函数。
function lempty(var L:list):boolean;
{若L为空表,则返回布尔值true,否则返回布尔值false}
begin
lempty:=(L.last=0);
end;
4.判满函数。
function lfull(var L:list):boolean;
{如果表中已装满元素,函数值为true,否则为false}
begin
lfull:=(L.last=lmaxsize);
end;
5.求首结点元素位置函数。
function lfirst(var L:list):lposition:
begin
if L.last=0
then lfirst:=0
else lfirst:=1;
end;
6.求尾结点元素位置函数。
function llast(var L:list):lposition:
begin
llast:=L.last;
end;
7.求前趋函数。
function lprior(p:lposition;var L:list):lposition;
{已知给定线性表L的一个元素的位序p,若1<p<=llength(L),则函数值为p的前趋位序,否则指出错误}
begin
if(p<=1)or(p>llength(L))
then
begin
lerro:=indexerro;
lprior:=0;
end
else lprior:=p-1;
end;
8.求后继函数。
function lnext(p:lposition;var L:list):lposition;
{已知给定线性表L的一个元素位序p,若1<=p<llength(L),则函数值为p.的后继,否则为空元素}
begin
if(p<=0)or(p>=llength(L))
then
begin
lerro:=indexerro;
lnext:=0;
end
else lnext:=p+1;
end;
9.取元素函数。
procedure lretrieve(p:lposition;var e:lelement;var L:list);
{若1<=p<=llength(L)则函数值为给定的线性表L中第i个数据元素,否则指出错误。p称为该数据元素在线性表中的位序}
begin
if(p<=0)or(p>llength(L))
then lerro:=indexerro
else e:=L.data[p];
end;
10.修改元素数据过程。
procedure lupdate(e:lelement;p:lposition;var L:list);
begin
if(p<=0)or(p>llength(L))
then lerro:=indexerro
else L.data[p]:=e;
end;
11.删除操作过程。
procedure ldelete(p:lposition;var L:list);
{若1<=p<=llength(L),删除给定线性表中第p个数据元素,使操作之前和度为n的线性表(a1,a2,…,ap-1,ap,…an)变成长度为n-1的线性表(a'1,a'2,…,a'p-1,a'p…a'n-1),其中当1<=j<=p-1时a'j=aj,当p<=j<=n-1时a'j=aj+1。若p<1或p>llength(L),则此操作无意义}
var i:lposition;
begin
if llength(L)=0
then lerro:=indexerro
else if(p<1)or(p>llength(L))
then lerro:=indexerro
else
begin
for i:=p to llength(L)-1 do
L.data[i]:=L.data[i+1]:{第i后元素逐个前移}
L.last:=L.last-1;{尾元素序号减1,即线性表长度减1}
end;
end;
12.后插操作过程。
procedure lisertafter(e:lelement;p:lposition;var L:list);
{在给定线性表中第p个元素之后插入一个新的数据元素e,使操作之前和度为n的线性表(a1,a2,…ap,ap+1,…an)变成长度为n+1的线性表(a'1,a'2,…a'p,e,a'p+2,…a'n),其中e 为操作后的线性表L、中敏p+1个数据元素,且当1<=i<=p时a'i=ai,当p+2<=i<=n+1时a'i=ai-1。可见此操作仅在1<=p<=n时可行}
var
i:lposition;
begin
if llength(L)=0
then
begin
L.data[1]:=e;
L.last:=1;
end
else if(p<0)or(p>llength(L))
then lerro:=indexerro;
else if llength(L)=lmaxsize
then lerro:=overflow
else
begin
for i:=llength(L)downto p+1 do
L.data[i+1]:=L.data[i];{从最后元素开始到第i个元素逐个后移}
L.data[p+1]:=e;{插入}
L.last:=L.last+1;{尾元素序号加1,即线性表长度加1}
end;
end;
13.判断两元素是否相同函数。
function lequal(e,f:lelement):boolean:
{若e,f值相等,函数值为true,否则flse}
begin
{example}
lequal:=(e.name=f.name)and(e.chinese=f.chinese)and(e.math=f.math)
and(e.sum=f.sum)and(e.average=f.average);
end;
14.定位函数。
function lfind(e.lelement;var L:list):lposition;
{给定值e,若线性表L中存在值和e相同的数据元素不止一个,则函数值为这此元素在线性表L中的位序的最小值}
var
p:integer;
begin
p:=1;
Lerro:=findfail;
lfind:=0;
while(Lerro=findfail)and(p<=llength(L))do
begin
if lequal(e,L.data[p])
then
begin
lfind:=p;
lerro:=noerro;
end;
p:=p+1;
end;
end;
15.前插过程。
在上述函数或过程的基础上,我们还可以根所需要增加一些有用的自定义函数或过程,例如下面的在一个元素前插过程:
procedure linserbefore(e:lelement;p:lposition;var L:list);
var
temp:lelement;
begin
if(p<0)or(p>llength(L))
then lerro:=indexerro
else if lempty(L)
then linsertafter(e,p,L);{调用后插过程}
else
begin
p:=lprior(p,L);{求p的前一个位置并把新结点插入其后}
linsertafter(e,p,L);{调用后插过程}
end;
end;
例题:用线性表编一个学生成绩表,并对其进行插入、修改、删除、追加、显示、退出等操作。
解答:
{
By Unite Space 2001
http://www.cpascal.com
e-mail:webmaster@cpascal.com
}
program data_structure_application_chapter2_sample_2;
uses crt;
const
lmaxsize=300;
type
lelement=record
name:string[8];
chinese:real;
math:real;
sum:real;
average:real;
end;
lposition=0..lmaxsize;
list=record
data:array[1..lmaxsize]of lelement;
last:lposition;
end;
listerro=(noerror,indexerror,findfail,overflow,underflow);
var
l:list;
lerro:listerro;
menu,p:integer;
e:lelement;
procedure lcreate(var l:list);
begin
l.last:=0;
lerro:=noerror;
end;
function llength(var l:list):lposition;
begin
llength:=l.last;
end;
function lempty(var l:list):boolean;
begin
if l.last=0 then lempty:=true
else lempty:=false;
end;
procedure linsertafter(e:lelement;p:lposition;var l:list);
var
i:lposition;
begin
if llength(l)=0
then
begin
l.data[1]:=e;
l.last:=1;
end
else if(p<0)or(p>llength(l))
then lerro:=indexerror
else if llength(l)=lmaxsize
then lerro:=overflow
else
begin
for i:=llength(l) downto p+1 do
l.data[i+1]:=l.data[i];
l.data[p+1]:=e;
inc(l.last);
end;
end;
procedure lupdate(e:lelement;p:lposition;var l:list);
begin
if (p<=0)or(p>llength(l))
then lerro:=indexerror
else l.data[p]:=e;
end;
procedure ldelete(p:lposition;var l:list);
var i:lposition;
begin
if llength(l)=0
then lerro:=indexerror
else if (p<1)or(p>llength(l))
then lerro:=indexerror
else
begin
for i:=p to llength(l)-1 do
l.data[i]:=l.data[i+1];
dec(l.last);
end;
end;
procedure erromessage;
begin
case lerro of
noerror:writeln('ok!');
indexerror:writeln('index error!');
findfail:writeln('find fail!');
overflow:writeln('overflow error!');
underflow:writeln('underflow error!');
end;
readln;
end;
procedure readrecord(var e:lelement);
begin
with e do
begin
write('name:');
readln(name);
write('chinese:');
readln(chinese);
write('math:');
readln(math);
sum:=chinese+math;
average:=sum/2;
end;
end;
procedure readposition(var p:integer;message:string);
begin
write('please input ',message,' position');
readln(p);
end;
procedure printlist(var l:list);
var
i:integer;
begin
if lempty(l)
then writeln('It is empty now!')
else
writeln('no':10,'name':10,'chinese':10,'math':10,'average':10);
for i:=1 to llength(l) do
with l.data[i] do
begin
writeln(i:10,name:10,chinese:10:1,math:10:1,average:10:1);
end;
end;
begin
lcreate(l);
repeat
clrscr;
lerro:=noerror;
write('1--insert,2--edit,3--delete,4--append,5--list,0--quit:');
readln(menu);
case menu of
1:begin
readrecord(e);
readposition(p,'insert');
linsertafter(e,p,l);
end;
2:begin
readrecord(e);
readposition(p,'edit');
lupdate(e,p,l);
end;
3:begin
readposition(p,'delete');
ldelete(p,l);
end;
4:begin
readrecord(e);
linsertafter(e,llength(l),l);
end;
5:printlist(l);
0:halt;
else
writeln('please input number of 0--4! press any key to continue.');
readln;
end;
erromessage;
until false;
end.
{
By Unite Space 2001
http://www.cpascal.com
e-mail:webmaster@cpascal.com
}

作 者:联合空间网络工作室
来 源:cpascal.com
共有4867位读者阅读过此文

  • 上篇文章数据结构-线性表 (一)
  • 下篇文章数据结构-线性表 (三)

  • 发送邮件
    保存页面 打印文章 HTML版本 发表评论

    □- 近期热门文章 □- 相关文章
    1. NOIP2006竞赛大纲 [8306]
    2. 七类高中生具有保送资格 [5910]
    3. NOI2006获奖选手名单 [4955]
    4. 关于举办NOIP2006模拟赛的通告 [4106]
    5. Turbo Pascal各语句运行速... [3594]
    6. Turbo王者归来新Delphi免费... [3181]
    7. IOI2006我国4名选手全部获得金... [2945]
    8. 关于APIO2007与IOI2007... [2763]
    9. noip倒计时 by 枯叶蝴蝶 [2683]
    10. 朱泽园:思想上的金牌更重要 [2168]
    谈谈数据结构
    趣谈数据结构(七)
    趣谈数据结构(六)
    趣谈数据结构(五)
    趣谈数据结构(四)
    趣谈数据结构(三)
    趣谈数据结构(二)
    趣谈数据结构(一)
    实数类型
    数据结构-线性表 (三)
     

    关于本站 | 合作伙伴 | 联系方式
    大榕树 版权所有 ©1999-2006 www.myDrs.org 闽ICP备05000721号