数据结构_广义表的运算

数据结构_广义表的运算
数据结构_广义表的运算

《数据结构》课程设计

题目:广义表的运算

广义表是线性表的推广。线性表的元素仅限于原子项。广义表的元素或者是原子,或者是一个广义表,有其自身结构。广义表通常用圆括号括起来,用逗号分隔其中的元素。为了区分原子和广义表,书写时用大写字母表示广义表,用小写字母表示原子。LS=(a1,a2,…,an),LS是广义表的名字,n为它的长度,若ai是广义表,则称它为LS的子表。若广义表非空(n>=1),则a1是LS的表头,其余元素组成的表(a2,…,an)称为LS的表尾。一个表展开后所含括号的层数称为广义表的深度。

本设计要求实现广义表的建立、查找、输出、取表头、取表尾及求深度等运算。选择合适的存储结构表示广义表,并能实现下列运算要求:

(1)用大写字母表示广义表,用小写字母表示原子,并提供设置广义表的值的功

能。

(2)取广义表L的表头和表尾的函数head(L)和tail(L)。

(3)能用这两个函数的复合形式求出广义表中的指定元素。

(4)由广义表的字符串形式到广义表的转换函数Lists Str_ToLists_(S);例如

Str_ToLists_(“ (a,(a,b),c)”)的值为一个广义表。

(5)由广义表到广义表的字符串形式的转换函数char * Lists_To_Str(L)。

(6)最好能设置多个广义表。

解:本题的解法如下:

1算法设计

1.由于广义表(a1,a2,…,an)中的数据元素可以具有不同的结构(或是原子或是列表)因此难以用顺序存储结构表示,通常采取链式存储结构,每个元素都可以用一个结点表示。一个表结点可由3个域组成:标志域,指针表头的指针域和指针表尾的指针域;而原子结点只需两个域:标志域和值域。

2.假设以字符串L=(a1,a2,…,an) 的形式定义广义表L,建立相应的存储结构。对广义表进行的操作下递归定义时,可以有两种方法。一种是把广义表分解成表头和表尾两部分;另一种是把广义表堪称含有n个并列子表(假设原子也视作子表)的表。在讨论建立广义表的存储结构时,这两种分析方法均可。

3.实现查找,即实现广义表的遍历。

4.取表头和表尾:广义表一般记做LS=(α

1,α

2

,…α

n

)其中,LS是广义表

LS=(α

1,α

2

,…α

n

)的名称,n是它的长度。在线性表的定义中,α

i

(1<=i<=n)

只限于单个元素,而在广义表的定义中,α

i

可以是单个元素,也可以是广义表,

分别称为广义表LS的原子和子表。当广义表非空时,称第一个元素α

i

为LS的表头,称其余的元素组成的表(α2,α3,…αn)为LS的表尾。

5.由广义表的字符串形式到广义表转换函数:由于S中的每个子串α

i

定义L 的一个子表,从而产生n 个子问题,即分别由这n个子串 (递归)建立n 个子表,再组合成一个广义表。其中:可以直接求解的两种简单情况为:以串‘()’建立的广义表是空表,由单字符建立的广义表只是一个原子结点。若是其他情况,因为第一个子表的标志域为一,代表指向广义表的头指针。指示表头的指针域指向第一个子表的头指针。相邻子表之间用表结点相连接。综上:若 S = '( )'则

L = NIL;否则,构造第一个表结点 *L,并从串S中分解出第一个子串α

1

,对应创建第一个子广义表L->ptr.hp;若剩余串非空,则构造第二个表结点

L->ptr.tp,并从串S中分解出第二个字串α

2

,对应创建第二个子广义表……以此类推直至剩余串为空串止。

6.由广义表到广义表的字符串形式

7.求深度:广义表深度定义为广义表中括弧的重数,是广义表的一种量度。例如,

多元多项式广义表的深度为多项式中变元的个数。设非空广义表为LS=(α

1

,α

2,…α

n

)其中α

i

(i=1,2,3…)或为原子或为LS的子表,则求LS的深度可

分解为n个子问题,每个子问题为求α

i 的深度,若α

i

是原子,则由定义其深度

为零,若α

i 是广义表,则和上述一样处理,而LS的深度为各α

i

(i=1,2,3…)

的深度中最大值加一。空表也是广义表,并由定义可知空表的深度为1。

由此可见,求广义表的深度递归算法有两个终结态:空表和原子,且只要求得αi

(i=1,2,3,…)的深度,广义表的深度就容易求得了。显然,它应比子表深度的最大值多1.

广义表 LS=(α

1,α

2

,…α

n

)的深度DEPTH(LS)的递归定义为

基本项:DEPTH(LS)=1当LS为空表时

DEPTH(LS)=0当LS为原子时

归纳项:DEPTH(LS)=1+Max{DEPTH(α

)}n>=1由此定义容易写出求深度的递归函数。假设L是GList型的变量则L=NULL表明广义表为空表,L->tag=0表明是原子。反之,L指向表结点,该结点中的hp指针指向表头,即为L的第一个子表,而结点中的tp指针所指表尾结点中的hp指针指向L的第二个子表。在第一层中由tp相连的所有尾结点中的hp指针均指向L的子表。由此可得广义表深度的递归算法。

2程序实现

上机实现算法时由于具体问题牵涉到各种方面,难以综合实现,可以分为几个小的模块将程序先进行初步整合

具体程序:

#include

#include

#include

class GenListNode{

friend class GenList;

public:

int utype; //0,1,2,3

union{

int intinfo;

char charinfo;

GenListNode* hlink;

}value;

GenListNode* tlink;

GenListNode(){}

};

class GenList{

public:

GenListNode * first;

int Sever( char* &hstr,char * &s );

void strncpy1( char* &hstr,char* &s,int comma );

GenListNode* CreatList( char* s );

void Creat( char* s );

void Display( void );

void Display( char * s ,GenListNode* ls);

void show( GenListNode* ls );

void head(GenListNode* &u);

void tail(GenListNode* &u);

int display(GenListNode* u1,GenListNode* u);

void find(char* s,GenListNode* &u);

};

void GenList::Creat( char* s )

{

first=CreatList(s);

}

GenListNode* GenList::CreatList( char* s )

{

GenListNode *ls,*head;

ls=new GenListNode();

head=ls;

ls->utype=0;

if( strlen(s)<=2 )

{

ls->tlink=NULL;

}else{

char* sub;

while( strlen(s)>2 ){

ls = ls->tlink = new GenListNode();

ls->utype=Sever(sub,s);

switch( ls->utype ){

case 1:ls->value.intinfo=atoi(sub);break;

case 2:ls->value.charinfo=sub[0];break;

case 3:ls->value.hlink=CreatList( sub );break;

}

}

ls->tlink=NULL;

}

return head;

}

int GenList::Sever( char* &hstr,char* &s )

{

char ch=s[0];

int n=strlen( s );

int i=0,k=0,comma=-1;

int x=0,y=0;

while( i

if( ch=='(' ){ k++;}

else{

if( ch==')' ){ k--;}

}

i++;

ch=s[i];

if(ch==',' && x==0){x=10;comma=i;}

if(k==1 && x<8){x++;if(x==2){comma=i;}}

}

if( k!=0 ){

cout<<"括号不配对! 退出程序!"<

exit(1);

}

if( comma==-1 ) {comma=n;}

strncpy1( hstr,s,comma ); //分割字符串

if( strlen(hstr)>=3 ){return 3;}

else{

if( hstr[0]<='9' && hstr[0]>='0' ){return 1;}

if( hstr[0]<='z' && hstr[0]>='a' ){return 2;}

}

return 1;

}

void GenList::strncpy1 (char* &hstr,char* &s,int comma ){ int n=strlen(s);

hstr=new char[n];

for( int t=0,i=1;i

hstr[t]=s[i];

t++;

}

hstr[t]='\0';

for( t=1,i=comma+1;i

{s[t]=s[i];}

s[t]='\0';

if(t==1){s[1]=')';s[2]='\0';}

}

void GenList::Display( void ){

show( first );

}

void GenList::Display( char * s ,GenListNode* ls)

{

int i=0;

if(ls->utype==0){

while( ls!=NULL ){

switch( ls->utype ){

case 0:s[i]='(';i++;cout<<"( "; break;

case

1:s[i]='0'+(ls->value.intinfo-0);i++;cout<value.intinfo;if(ls->t link!=NULL){s[i]=',';i++;cout<<" , ";} break;

case

2:s[i]=ls->value.charinfo;i++;cout<value.charinfo;if(ls->tlink!= NULL){s[i]=',';i++;cout<<" , ";} break;

case

3:show( ls->value.hlink );if(ls->tlink!=NULL){s[i]=',';i++;cout<<" , ";} break;

}

ls=ls->tlink;

}

s[i]=')';i++;

cout<<" ) "<

s[i]='\0';

}else{

while( ls!=NULL ){

switch( ls->utype ){

case 0:s[i]='(';i++;cout<<"( "; break;

case

1:s[i]='0'+(ls->value.intinfo-0);i++;cout<value.intinfo;if(ls->t

link!=NULL){s[i]=',';i++;cout<<" , ";} break;

case

2:s[i]=ls->value.charinfo;i++;cout<value.charinfo;if(ls->tlink!= NULL){s[i]=',';i++;cout<<" , ";} break;

case 3:show( ls->value.hlink ); break;

}

ls=ls->tlink;

}

cout<

s[i]='\0';

}

}

void GenList::show( GenListNode* ls )

{

if(ls->utype==0){

while( ls!=NULL ){

switch( ls->utype ){

case 0:cout<<"( "; break;

case 1:cout<value.intinfo;if(ls->tlink!=NULL){cout<<" , ";} break;

case 2:cout<value.charinfo;if(ls->tlink!=NULL){cout<<" , ";} break;

case 3:show( ls->value.hlink );if(ls->tlink!=NULL){cout<<" , ";}

break;

}

ls=ls->tlink;

}

cout<<" ) ";

}else{

while( ls!=NULL ){

switch( ls->utype ){

case 0:cout<<"( "; break;

case 1:cout<value.intinfo;if(ls->tlink!=NULL){cout<<" , ";} break;

case 2:cout<value.charinfo;if(ls->tlink!=NULL){cout<<" , ";} break;

case 3:show( ls->value.hlink ); break;

}

ls=ls->tlink;

}

}

}

void GenList::head(GenListNode* &u)

{

if(first->tlink!=NULL){

u=new GenListNode;

u->utype=first->tlink->utype;

switch( u->utype ){

case 1:u->value.intinfo=first->tlink->value.intinfo;

break;

case 2:u->value.charinfo=first->tlink->value.charinfo;

break;

case 3: u->value.hlink=first->tlink->value.hlink ;

break;

}

if(first->tlink!=NULL){

first->tlink=first->tlink->tlink;}

u->tlink=NULL;

}else{cout<<"元素列表为空。"<

}

void GenList::tail(GenListNode* &u)

{

GenListNode* x;

x=first;

if(x->tlink!=NULL){

for(;x->tlink->tlink!=NULL;)

{

x=x->tlink;

}

u=new GenListNode;

u->utype=x->tlink->utype;

switch( u->utype ){

case 1:u->value.intinfo=x->tlink->value.intinfo; break;

case 2:u->value.charinfo=x->tlink->value.charinfo; break;

case 3: u->value.hlink=x->tlink->value.hlink ; break;

}

if(x->tlink!=NULL){

x->tlink=NULL;}

u->tlink=NULL;

}else{cout<<"元素列表为空。"<

}

void GenList::find(char* s,GenListNode* &u)

{

int n=strlen(s);

char * s1;

int x=0,y=0,o=0,j=0;

bool i=0;

if(n=1){

if(s[0]<='9' && s[0]>='0'){

for(;first->tlink!=NULL ;){

head(u);

if(u->value.intinfo==s[0]){j=91;cout<<"找到元素。"<

}

}

if(s[0]<='z' && s[0]>='a'){

for(;first->tlink!=NULL ;){

head(u);

if(u->value.charinfo==s[0]){j=91;cout<<"找到元素。"<

}

}

}

if(n>=2){

GenListNode* p;

for(;first->tlink!=NULL ;){

head(u);

p=u->value.hlink;

p=p->tlink;

for(x=1,y=1;x

if(s[x]<='9' && s[x]>='0'){

s1[0]=s[x];

s1[1]='\0';

o=atoi(s1);

if(p->value.intinfo==o){if(p->tlink!=NULL)p=p->tlink;}

}

if(s[x]<='z' && s[x]>='a'){

if(p->value.charinfo==s[x]){if(p->tlink!=NULL)p=p->tlink;}

}

}

if(p->tlink==NULL){j=91;cout<<"找到元素。"<

}

if(j!=91){cout<<"无该元素。"<

}

int GenList::display(GenListNode* u1,GenListNode* u)

{

int x=0;

for(;u1->tlink!=NULL ;){

if(u->utype==u1->utype){

switch( u->utype ){

case 1:if(u->value.intinfo==u1->value.intinfo){x=1;} break;

case 2:if(u->value.charinfo==u1->value.charinfo){x=1;} break;

case 3: if(display(u1->value.hlink,u->value.hlink)){x=1;} break;

}

}

u1=u1->tlink;

}

return x;

}

int main( void ){

char s[45];

char s1[45];

char s2[45];

char s5[45];

int i;

GenListNode* u,* x;

cout<<"*************************************广义表************************************"<

cout<<"*******************请输入广义表like:(a,b,c,d,(1,2,3,d),f)******************* "<

cin>>s;

GenList A;

A.Creat(s);

cout<<"1,********取头结点********"<

cout<<"2,********取尾结点********"<

cout<<"3,******查找特定元素******"<

cout<<"4,***将广义表转换成字符***"<

cout<<"5,*将广义表转换成字符类型*"<

cout<<"0,**********退出**********"<

cout<<"执行:";

cin>>i;

for(;i!=0;cin>>i){

switch(i)

{

case 0:

break;

case 1:A.head(u);

A.show(u);break;

case 2:A.tail(u);

A.show(u);break;

case 3:

cout<<"********输入查找元素*******"<

cin>>s1;

cout<

A.find(s1,u);

A.show(u);

u=NULL;

break;

case 4:

A.Display();

cout<

break;

case 5:

cout<

A.Display(s5,A.first);

A.show(u);

u=NULL;

break;

default:

cout<<"*****请输入正确的口令!*****";

break;

}

cout<

cout<<"1,********取头结点********"<

cout<<"2,********取尾结点********"<

cout<<"3,******查找特定元素******"<

cout<<"4,***将广义表转换成字符***"<

cout<<"5,*将广义表转换成字符类型*"<

cout<<"0,**********退出**********"<

cout<<"执行:";

}

return 1;

}

3总结

在拿到题目进行设计时,我首先考虑到问题可以分为几个比较简单的小问题依次解决,于是我化整为零,逐个找解决问题的办法,这样设计出的程序条理比较清晰,易于编辑。但是这就带来了整合程序时的麻烦,我们力求在一个程序中尽可能解决多的问题,但由于水平所限,完成的不是很好。

通过这次课程设计,我感到数据结构的算法实现必须要有深厚的变成技术作为基础。遇到问题时首先应运用数据结构相关知识写出问题算法,然后根据算法写出相应的程序,最后调试。其中算法时关键,程序编写是重点。在以后的学习中,我还要加强这两个方面的学习,不断提高运用计算机解决问题的能力。

(完整word版)数据结构第五章数组和广义表习题及答案

习题五数组和广义表 一、单项选择题 1.常对数组进行的两种基本操作是() A.建立与删除 B. 索引与修改 C. 查找与修改 D. 查找与索引2.对于C语言的二维数组DataType A[m][n],每个数据元素占K个存储单元,二维数组中任意元素a[i,j] 的存储位置可由( )式确定. A.Loc[i,j]=A[m,n]+[(n+1)*i+j]*k B.Loc[i,j]=loc[0,0]+[(m+n)*i+j]*k C.Loc[i,j]=loc[0,0]+[(n+1)*i+j]*k D.Loc[i,j]=[(n+1)*i+j]*k 3.稀疏矩阵的压缩存储方法是只存储 ( ) A.非零元素 B. 三元祖(i,j, aij) C. aij D. i,j 4. 数组A[0..5,0..6]的每个元素占五个字节,将其按列优先次序存储在起始地址为1000的内存单元中,则元素A[5,5]的地址是( )。 A. 1175 B. 1180 C. 1205 D. 1210 5. A[N,N]是对称矩阵,将下面三角(包括对角线)以行序存储到一维数组T[N(N+1)/2]中,则对任一上三角元素a[i][j]对应T[k]的下标k是()。 A. i(i-1)/2+j B. j(j-1)/2+i C. i(j-i)/2+1 D. j(i-1)/2+1 6. 用数组r存储静态链表,结点的next域指向后继,工作指针j指向链中结点,使j 沿链移动的操作为( )。 A. j=r[j].next B. j=j+1 C. j=j->next D. j=r[j]-> next 7. 对稀疏矩阵进行压缩存储目的是()。 A.便于进行矩阵运算 B.便于输入和输出 C.节省存储空间 D.降低运算的时间复杂度 8. 已知广义表LS=((a,b,c),(d,e,f)),运用head和tail函数取出LS中原子e的运算是( )。 A. head(tail(LS)) B. tail(head(LS)) C. head(tail(head(tail(LS))) D. head(tail(tail(head(LS)))) 9. 广义表((a,b,c,d))的表头是(),表尾是()。 A. a B.() C.(a,b,c,d) D.(b,c,d) 10. 设广义表L=((a,b,c)),则L的长度和深度分别为()。 A. 1和1 B. 1和3 C. 1和2 D. 2和3 11. 下面说法不正确的是( )。 A. 广义表的表头总是一个广义表 B. 广义表的表尾总是一个广义表 C. 广义表难以用顺序存储结构 D. 广义表可以是一个多层次的结构 二、填空题 1.通常采用___________存储结构来存放数组。对二维数组可有两种存储方法:一种是以___________为主序的存储方式,另一种是以___________为主序的存储方式。 2. 用一维数组B与列优先存放带状矩阵A中的非零元素A[i,j] (1≤i≤n,i-2≤j≤i+2),B 中的第8个元素是A 中的第_ _行,第_ _列的元素。

数据结构第五章数组和广义表

第五章数组和广义表:习题 习题 一、选择题 1.假设以行序为主序存储二维数组A[1..100,1..100],设每个数据元素占两个存储单元,基地址为10,则LOC(A[5,5])=( )。 A. 808 B. 818 C. 1010 D. 1020 2.同一数组中的元素( )。 A. 长度可以不同B.不限C.类型相同 D. 长度不限 3.二维数组A的元素都是6个字符组成的串,行下标i的范围从0到8,列下标j的范圈从1到10。从供选择的答案中选出应填入下列关于数组存储叙述中( )内的正确答案。 (1)存放A至少需要( )个字节。 (2)A的第8列和第5行共占( )个字节。 (3)若A按行存放,元素A[8]【5]的起始地址与A按列存放时的元素( )的起始地址 一致。 供选择的答案: (1)A. 90 B. 180 C. 240 D. 270 E.540 (2) A. 108 B. 114 C. 54 D. 60 E.150 (3)A.A[8][5] B. A[3][10] c.A[5][8] D.A[O][9] 4.数组与一般线性表的区别主要是( )。 A.存储方面 B.元素类型方面 C.逻辑结构方面 D.不能进行插入和删除运算 5.设二维数组A[1..m,1..n]按行存储在数组B[1..m×n]中,则二维数组元素A [i,j]在一维数组B中的下标为( )。 A. (i-l)×n+j B. (i-l)×n+j-l C.i×(j-l) D. j×m+i-l 6.所谓稀疏矩阵指的是( )。 A.零元素个数较多的矩阵 B.零元素个数占矩阵元素中总个数一半的矩阵 C.零元素个数远远多于非零元素个数且分布没有规律的矩阵 D.包含有零元素的矩阵 7.对稀疏矩阵进行压缩存储的目的是( )。 A.便于进行矩阵运算 B.便于输入和输出 C.节省存储空间 D. 降低运算的时间复杂度 8.稀疏矩阵一般的压缩存储方法有两种,即( )。 A.二维数组和三维数组 B.三元组和散列 C.三元组和十字链表 D.散列和十字链表

数据结构(C语言版)第5章 数组和广义表

第 5 章数组和广义表 一、选择题 为第一元素,其 1.设有一个10阶的对称矩阵A,采用压缩存储方式,以行序为主存储,a 11 的地址为()。【燕山大学 2001 一、2 存储地址为1,每个元素占一个地址空间,则a 85 (2分)】 A. 13 B. 33 C. 18 D. 40 2. 有一个二维数组A[1:6,0:7] 每个数组元素用相邻的6个字节存储,存储器按字节编址, 那么这个数组的体积是(①)个字节。假设存储数组元素A[1,0]的第一个字节的地址是0, 则存储数组A的最后一个元素的第一个字节的地址是(②)。若按行存储,则A[2,4]的第 一个字节的地址是(③)。若按列存储,则A[5,7]的第一个字节的地址是(④)。就一般情 况而言,当(⑤)时,按行存储的A[I,J]地址与按列存储的A[J,I]地址相等。供选择的 答案:【上海海运学院 1998 二、2 (5分)】 ①-④: A.12 B. 66 C. 72 D. 96 E. 114 F. 120 G. 156 H. 234 I. 276 J. 282 K. 283 L. 288 ⑤: A.行与列的上界相同 B. 行与列的下界相同 C. 行与列的上、下界都相同 D. 行的元素个数与列的元素个数相同 3. 设有数组A[i,j],数组的每个元素长度为3字节,i的值为1 到8 ,j的值为1 到10, 数组从内存首地址BA开始顺序存放,当用以列为主存放时,元素A[5,8]的存储首地址为( )。 A. BA+141 B. BA+180 C. BA+222 D. BA+225 【南京理工大学 1997 一、8 (2分)】 4. 假设以行序为主序存储二维数组A=array[1..100,1..100],设每个数据元素占2个存 储单元,基地址为10,则LOC[5,5]=()。【福州大学 1998 一、10 (2分)】 A. 808 B. 818 C. 1010 D. 1020 5. 数组A[0..5,0..6]的每个元素占五个字节,将其按列优先次序存储在起始地址为1000 的内存单元中,则元素A[5,5]的地址是( )。【南京理工大学 2001 一、13 (1.5分)】 A. 1175 B. 1180 C. 1205 D. 1210 6. 有一个二维数组A[0:8,1:5],每个数组元素用相邻的4个字节存储,存储器按字节编址, 假设存储数组元素A[0,1]的第一个字节的地址是0,存储数组A的最后一个元素的第一个字 节的地址是(①)。若按行存储,则A[3,5]和 A[5,3]的第一个字节的地址是(②) 和(③)。若按列存储,则A[7,1]和A[2,4]的第一个字节的地址是(④)和(⑤)。【上海海运学院 1996 二、1 (5分)】 ①-⑤:A.28 B.44 C.76 D.92 E.108 F.116 G.132 H.176 I.184 J.188 7. 将一个A[1..100,1..100]的三对角矩阵,按行优先存入一维数组B[1‥298]中,A中元 (即该元素下标i=66,j=65),在B数组中的位置K为()。供选择的答案: 素A 6665 A. 198 B. 195 C. 197 【北京邮电大学 1998 二、5 (2分)】 8. 二维数组A的元素都是6个字符组成的串,行下标i的范围从0到8,列下标j的范圈 从1到10。从供选择的答案中选出应填入下列关于数组存储叙述中()内的正确答案。(1)存放A至少需要()个字节; (2)A的第8列和第5行共占()个字节; (3)若A按行存放,元素A[8,5]的起始地址与A按列存放时的元素()的起始地

数据结构练习题-数组和广义表

已知二维数组A[3][5],其每个元素占3个存储单元,并且A[0][0]的存储地址为1200。 求元素A[1][3]的存储地址(分别对以行序和列序为主序存储进行讨论),该数组共占用多少个存储单元? 【解答】按照以行序为主序存储公式: LOC(i,j)=LOC(c1,c2)+[(i-c1)*(d2-c2+1)+(j-c2)]*L 在C语言中有:LOC(i,j)=LOC(0,0)+(i*(d2+1)+j)*L 则: LOC(A[1][3])=1200+(1*5+3)*3=1224 (按行序存储) LOC(A[1][3])=1200+(3*3+1)*3=1230 (按列序存储) 有一个10阶的对称矩阵A,采用压缩存储方式以行序为主序存储,A[1][1]为第一元素,其存储地址为1,每个元素占一个地址空间,求A[7][5]和A[5][6]的地址。 【解答】按照公式: LOC(A[7][5])=7(7-1)/2+5 = 26 LOC(A[5][6])=LOC(A[6][5])=6(6-1)/2+5=20 设有一个二维数组A[m][n],设A[0][0]存放位置在644,A[2][2]存放位置在676,每个元素占一个空间,问A[3][3]存放在什么位置? 因为A[0][0]存放位置在644,A[2][2]存放位置在676,每个元素占一个空间,说明一行有15个元素(算法:(676-2-644)/2)。A[3][3]存放位置是692。 二维数组A[9][10]的元素都是6个字符组成的串,请回答下列问题: (1)存放A至少需要( )个字节; (2)A的第7列和第4行共占( )个字节; (3)若A按行存放,元素A[7][4]的起始地址与A按列存放时哪一个元素的起始地址一致。 【解答】按照题5.1给出的公式: (1)存放A需要9*10*6=540个字节 (2)A的第7列和第行共占(9+10-1)*6=108个字节(3) LOC(A[7][4])= LOC(A[0][0])+[7*10+4]*L (按行序存储) LOC(A[i][j])= LOC(A[0][0])+[j*9+i]*L (按列序存储,0<=i<=8,0<=j<=9)所以,i=2,j=8。 即元素A[7][4]的起始地址与A按列存放时A[2][8]的起始地址一致。 什么是广义表?请简述广义表和线性表的主要区别。 【解答】广义表是零至多个元素的有限序列,广义表中的元素可以是原子,也可以是子表。 从“元素的有限序列”角度看,广义表满足线性结构的特性:在非空线性结构中,只有一个 称为“第一个”的元素,只有一个称为“最后一个”的元素,第一元素有后继而没有前驱, 最后一个元素有前驱而没有后继,其余每个元素有唯一前驱和唯一后继。从这个意义上说, 广义表属于线性结构。当广义表中的元素都是原子时,广义表就蜕变为线性表。 求广义表D=(a,(b,(),c),((d),e))的长度和深度。 【解答】3和3

数据结构_广义表的运算

《数据结构》课程设计 题目:广义表的运算 广义表是线性表的推广。线性表的元素仅限于原子项。广义表的元素或者是原子,或者是一个广义表,有其自身结构。广义表通常用圆括号括起来,用逗号分隔其中的元素。为了区分原子和广义表,书写时用大写字母表示广义表,用小写字母表示原子。LS=(a1,a2,…,an),LS是广义表的名字,n为它的长度,若ai是广义表,则称它为LS的子表。若广义表非空(n>=1),则a1是LS的表头,其余元素组成的表(a2,…,an)称为LS的表尾。一个表展开后所含括号的层数称为广义表的深度。 本设计要求实现广义表的建立、查找、输出、取表头、取表尾及求深度等运算。选择合适的存储结构表示广义表,并能实现下列运算要求: (1)用大写字母表示广义表,用小写字母表示原子,并提供设置广义表的值的功 能。 (2)取广义表L的表头和表尾的函数head(L)和tail(L)。 (3)能用这两个函数的复合形式求出广义表中的指定元素。 (4)由广义表的字符串形式到广义表的转换函数Lists Str_ToLists_(S);例如 Str_ToLists_(“ (a,(a,b),c)”)的值为一个广义表。 (5)由广义表到广义表的字符串形式的转换函数char * Lists_To_Str(L)。 (6)最好能设置多个广义表。 解:本题的解法如下: 1算法设计 1.由于广义表(a1,a2,…,an)中的数据元素可以具有不同的结构(或是原子或是列表)因此难以用顺序存储结构表示,通常采取链式存储结构,每个元素都可以用一个结点表示。一个表结点可由3个域组成:标志域,指针表头的指针域和指针表尾的指针域;而原子结点只需两个域:标志域和值域。 2.假设以字符串L=(a1,a2,…,an) 的形式定义广义表L,建立相应的存储结构。对广义表进行的操作下递归定义时,可以有两种方法。一种是把广义表分解成表头和表尾两部分;另一种是把广义表堪称含有n个并列子表(假设原子也视作子表)的表。在讨论建立广义表的存储结构时,这两种分析方法均可。 3.实现查找,即实现广义表的遍历。 4.取表头和表尾:广义表一般记做LS=(α 1,α 2 ,…α n )其中,LS是广义表 LS=(α 1,α 2 ,…α n )的名称,n是它的长度。在线性表的定义中,α i (1<=i<=n) 只限于单个元素,而在广义表的定义中,α i 可以是单个元素,也可以是广义表, 分别称为广义表LS的原子和子表。当广义表非空时,称第一个元素α i 为LS的表头,称其余的元素组成的表(α2,α3,…αn)为LS的表尾。 5.由广义表的字符串形式到广义表转换函数:由于S中的每个子串 i 定义L 的

数据结构数组和广义表自测题(附答案)

第4~5章串和数组 一、填空题 1. 不包含任何字符(长度为0)的串称为空串;由一个或多个空格(仅由空格符)组成的串称为空白串。 2. 设S=“A;/document/Mary.doc”,则strlen(s)= 20, “/”的字符定位的位置为3。 4. 子串的定位运算称为串的模式匹配;被匹配的主串称为目标串,子串称为模式。 5. 设目标T=”abccdcdccbaa”,模式P=“cdcc”,则第6次匹配成功。 6. 若n为主串长,m为子串长,则串的古典(朴素)匹配算法最坏的情况下需要比较字符的总次数为 (n-m+1)*m。 7. 假设有二维数组A6×8,每个元素用相邻的6个字节存储,存储器按字节编址。已知A的起始存储位置(基 1282;若按行地址)为1000,则数组A的体积(存储量)为288 B ;末尾元素A 57的第一个字节地址为 (8+4)×6+1000=1072;若按列存储时,元素A47的第一个字节地址存储时,元素A 14的第一个字节地址为 为(6×7+4)×6+1000)=1276。(注:数组是从0行0列还是从1行1列计算起呢?由末单元为A 57可知,是从0行0列开始!) 8.设数组a[1?60, 1?70]的基地址为2048,每个元素占2个存储单元,若以列序为主序顺序存储,则元素 a[32,58]的存储地址为8950。答:不考虑0行0列,利用列优先公式: LOC(a ij)=LOC(a c1, c2)+[(j-c2)*(d1-c1+1)+i-c1)]*L得:LOC(a32,58)=2048+[(58-1)*(60-1+1)+32-1]]*2=8950 9. 三元素组表中的每个结点对应于稀疏矩阵的一个非零元素,它包含有三个数据项,分别表示该元素 的行下标、列下标和元素值。 10.求下列广义表操作的结果: (1)GetHead【((a,b),(c,d))】=== (a, b) ; //头元素不必加括号 (2)GetHead【GetTail【((a,b),(c,d))】】=== (c,d) ;

中南大学数据结构与算法第5章数组和广义表课后作业答案

第5章数组与广义表习题练习答案 5.1请按行及按列优先顺序列出四维数组A2*3*2*3的所有元素在内存中的存储次序,开始结点为a0000。 解: 按行优先的顺序排列时,先变化右边的下标,也就是右到左依次变化,这个四维数组的排列是这样的:(将这个排列分行写出以便与阅读,只要按从左到右的顺序存放就是在内存中的排列位置) a0000a0001a0002 a0010a0011a0012 a0100a0101a0102 a0110a0111a0112 a0200a0201a0202 a0210a0211a0212 a1000a1001a1002 a1010a1011a1012 a1100a1101a1102 a1110a1111a1112 a1200a1201a1202 a1210a1211a1212 按列优先的顺序排列恰恰相反,变化最快的是左边的下标,然后向右变化,所以这个四维数组的排列将是这样的,(这里为了便于阅读,也将其书写为分行形式): a0000a1000 a0100a1100 a0200a1200 a0010a1010 a0110a1110 a0210a1210 a0001a1001 a0101a1101

a0201a1201 a0011a1011 a0111a1111 a0211a1211 a0002a1002 a0102a1102 a0202a1202 a0012a1012 a0112a1112 a0212a0212 5.2 给出C语言的三维数组地址计算公式。 解: 因为C语言的数组下标下界是0,所以 Loc(A mnp)=Loc(A000)+((i*n*p)+k)*d 其中Amnp表示三维数组。Loc(A000)表示数组起始位置。i、j、k表示当前元素的下标,d表示每个元素所占单元数。 5.3设有三对角矩阵A n*n,将其三条对角线上的元素逐行地存储到向量B[0...3n-3]中,使得B[k]=a ij,求: (1)用i , j 表示k的下标变换公式。 (2)用k 表示i,j 的下标变换公式。 (1) 解: 要求i,j 到k 的下标变换公式,就是要知道在k之前已有几个非零元素,这些非零元素的个数就是k 的值,一个元素所在行为i,所在列为j,则在其前面已有的非零元素个数为: (i*3-1)+j-(i+1) 其中(i*3-1)是这个元素前面所有行的非零元素个数,j-(i+1)是它所在列前面的非零元素个数 化简可得: k=2i+j; // c下标是从0开始的。

数据结构实验广义表

《数据结构》实验报告 ◎实验题目: 广义表的创建与遍历。 ◎实验目的:熟悉和掌握广义表的定义及结构,可以创建及遍历广义表。 ◎实验内容:利用栈创建以及遍历一个广义表。 一、需求分析 1.本演示程序中,输入广义表的内容应为任意符合广义表要求结构的数据,将数据输入创建广义表中,再通过遍历程序将其以广义表形式输出。 2.本程序是以用户与计算机的对话方式执行,运行程序后,按要求输入数据即可。 3.程序执行的命令包括: (1)构造广义表与链栈,并初始化(2)输入广义表(3)输出广义表(4)结束 4.测试数据: 输入((),((a,b),(c,d))) 输出((),((a,b),(c,d))) 错误输入:如果输入((),((a,b),(c,d)))) 输出((),((a,b),(c,d))) 二概要设计 为了实现上述操作,应以广义链表为存储结构。 1.基本操作: Snode *Push(Snode *top,node *input) 实现指针入栈 Snode *Pop(Snode *top,node **output) 实现指针出栈 node *create() 广义表的建立 void print(node *head) 广义表的输出 2.本程序包括三个模块: (1)主程序模块 (2)广义表的创建 (3)广义表的遍历 (4)入栈模块 (5)出栈模块 (6) 三 1.元素类型、节点类型和指针类型 //定义广义表 typedef struct node

{ char data; /*存储数据*/ int tag; /*用以标记,标记为1时为左括号,标记为0时为字符,标记为-1时为新开辟节点*/ struct node *hp; /*该指针指向字表*/ struct node *tp; /*该指针指向后续节点*/ }node; //定义链栈 typedef struct Snode { node *data; struct Snode *next; }Snode; Snode *top node *input Snode *s Snode *p; node **output node *p,*q,*head; 2.每个模块的分析: (1)主程序模块: int main() { node *head; printf("请输入广义表:\n"); head=create(); printf("该广义表为:\n"); print(head); getchar(); getchar(); return 0; } (2)广义表的创建: node *create() { node *p,*q,*head; /*指针p是一个移动指针,指针q用以开辟新节点,head为头指针*/ char x; /*输入字符*/ Snode *top; /*栈顶指针*/ top=NULL; /*栈顶置空*/ q=(node *)malloc(sizeof(node)); /*申请新节点*/ q->tag=1; /*广义表形式第一个字符必为左括号*/ scanf("%c",&x); /*输入字符*/ head=q; /*广义表头结点指向新开辟节点*/

数据结构答案-第6章-多维数组和广义表学习指导

【 第6章多维数组和广义表 知识点分析 1.多维数组概念 多维数组是向量的推广,对于二维数组A m×n既可以看成m行向量组成的向量,也可以看成n行向量组成的向量。多维数组在计算机中有两种存储形式:按行优先顺序存储和按列优先顺序存储。 2.多维数组的存储 二维数组a ij的地址为:LOC(a ij) = LOC(a00) + ( i×n + j ) × d (0下标起始的语言) 三维数组a ijk的地址为:LOC(a ijk)=LOC(a000)+( (i×n×p+ j×p +k) ×d (0下标起始的语言) d为每个数据元素占有的字节数。 … 3.特殊矩阵 在矩阵中非零元素或零元素的分布有一定规律的矩阵称为特殊矩阵,如三角矩阵、对称矩阵、稀疏矩阵等。当矩阵的阶数很大时,用普通的二维数组存储这些特殊矩阵将会占用很多的存储单元。从节约存储空间的角度考虑,以下特殊矩阵的存储方法。 (1)对称矩阵 对称矩阵是一种特殊矩阵,n阶方阵的元素满足性质:a ij=a ji(0≤i , j≤n-1)。对称矩阵是关于主对角线的对称,因此只需存储上三角或下三角部分的数据即可。 (2)三角矩阵 三角矩阵的特殊性是以主对角线划分矩阵。下三角矩阵,主对角线以上均为同一个常数;上三角矩阵,主对角线以下均为同一个常数,可以采用压缩存储。 (3)稀疏矩阵 在m*n的矩阵中有t个非零元素,且t远小于m×n,这样的矩阵称稀疏矩阵。为了节约存储空间,稀疏矩阵中零元素无需存储,只需存储矩阵中的非零元素。稀疏矩阵常用的有:三元组表存储、带行指针的链表存储、十字链表存储等存储方法。 @ 4.广义表 广义表是n(n≥0)个数据元素的有序序列,广义表的元素可以是单元素,也可以是一个广义表。由于广义表的元素有两种形式,所以其结点的存储形式也有两种: (1)表结点由标志域、表头指针域、表尾指针域组成。 (2)原子结点由标志域和值域组成。 5.广义表与线性表的区别和联系 线性表是具有相同类型的n个数据元素的有限序列,记为a1、a2、a3、……、a n。广义表也是n个数据元素的有限序列,记为a1、a2、a3、……、a n。线性表中的元素必须具有相同的类型,而广义表中的成员,既可以是单个元素(原子),也可以是一个广义表(子表)。当广义表中的每一个a i元素都是数据元素,且具有相同类型时,则它就是一个线性表,因此可以说广义表是线性表的一种推广,或者说线性表是广义表的一个特例。 典型习题分析 【例1】设二维数组A5×6的每个元素占4个字节,存储器按字节编址。已知A的起始地址为2000,计算:

广州大学松田学院6数据结构复习题-广义表-参考答案

6数据结构复习题(广义表) 一.判断题(下列各题,正确的请在前面的括号内打√;错误的打╳) (√)(1)n维的多维数组可以视为n-1维数组元素组成的线性结构。 (√)(2)稀疏矩阵中非零元素的个数远小于矩阵元素的总数。 (ㄨ)(3)上三角矩阵主对角线以上(不包括主对角线中的元素),均为常数C。 (√)(4)数组元素可以由若干个数据项组成。 (√)(5)数组的三元组表存储是对稀疏矩阵的压缩存储。 (ㄨ)(6)任何矩阵都可以进行压缩存储。 (ㄨ)(7)广义表是线性表的推广,所以广义表也是线性表。 (ㄨ)(8)广义表LS=(a0,a1,……a n-1),则a n-1是其表尾。 (√)(9)广义表((a,b),a,b)的表头和表尾是相等的。 (√)(10)一个广义表的表尾总是一个广义表。 二.填空题 (1)多维数组的顺序存储方式有按行优先顺序存储和按列优先顺序存储两种。 (2)在多维数组中,数据元素的存放地址可以直接通过地址计算公式算出,所以多维数组是一种随机存取结构。 (3)在n维数组中的每一个元素最多可以有 n 个直接前驱。 (4)输出二维数组A[n][m]中所有元素值的时间复杂度为O(n*m) 。(5)数组元素a[0..2][0..3]的实际地址上2000,元素长度是4,则LOC[1,2]= 2024 。LOC[1,2]=2000+(1*4+2)*4 (6)稀疏矩阵的三元组有 3 列。 (7)稀疏矩阵的三元组中第1列存储的是数组中非零元素所在的行数。(8)n阶对称矩阵,如果只存储下三角元素,只需要 n(n-1)/2 个存储单元。(9)稀疏矩阵A如下图所示,其非零元素存于三元组表中,三元组(4,1,5) 按列优先顺序存储在三元组表的第 4 项。 A=

《数据结构》习题集:章 数组与广义表

第5章数组与广义表 一、选择题 1.在以下讲述中,正确的是(B )。 A、线性表的线性存储结构优于链表存储结构 B、二维数组是其数据元素为线性表的线性表 C、栈的操作方式是先进先出 D、队列的操作方式是先进后出 2.若采用三元组压缩技术存储稀疏矩阵,只要把每个元素的行下标和列下标互换,就完成了对该矩阵的转 置运算,这种观点( B )。 A、正确 B、错误 3.二维数组SA 中,每个元素的长度为3 个字节,行下标I 从0 到7,列下标J 从0 到9,从首地址SA 开始 连续存放在存储器内,该数组按列存放时,元素A[4][7]的起始地址为( B )。 A、SA+141 B、SA+180 C、SA+222 D、SA+225 4.数组SA 中,每个元素的长度为3 个字节,行下标I 从0 到7,列下标J 从0 到9,从首地址SA 开始连续 存放在存储器内,存放该数组至少需要的字节数是( C )。 A、80 B、100 C、240 D、270 5.常对数组进行的两种基本操作是(C )。 A、建立与删除 B、索引和修改 C、查找和修改 D、查找和索引 6.将一个A[15][15]的下三角矩阵(第一个元素为A[0][0]),按行优先存入一维数组B[120]中,A 中元素A[6][5] 在B 数组中的位置K 为(B )。 A、19 B、26 C、21 D、15 7.若广义表A 满足Head(A)=Tail(A),则A 为(B )。 A、() B、(()) C、((),()) D、((),(),()) 8.广义表((a),a)的表头是(C ),表尾是(C )。 A、a B、b C、(a) D、((a)) 9.广义表((a,b),c,d)的表头是(C ),表尾是(D )。 A、a B、b C、(a,b) D、(c,d) 10.广义表((a))的表头是(B ),表尾是(C )。 A、a B、(a) C、() D、((a)) 11.广义表(a,b,c,d)的表头是(A ),表尾是(D )。 A、a B、(a) C、(a,b) D、(b,c,d) 12.广义表((a,b,c,d))的表头是(C ),表尾是(B )。 A、a B、() C、(a,b,c,d) D、((a,b,c,d)) 13.下面结论正确的是(BC )。 A、一个广义表的表头肯定不是一个广义表 B、一个广义表的表尾肯定是一个广义表 C、广义表L=((),(A,B))的表头为空表 D、广义表中原子个数即为广义表的长度 14.广义表A=(A,B,(C,D),(E,(F,G))),则head(tail(head(tail(tail(A)))))=( D ) A、(G) B、(D) C、C D、D 15.已知广义表L=((x,y,z),a,(u,t,w)),从L 表中取出原子项t 的操作是(D )。 A 、Head(Head(Tail(Tail(L)))) B 、Tail(Head(Head(Tail(L)))) C 、Head(Tail(Head(Tail(L)))) D 、Head(Tail(Head(Tail(Tail(L)))))

第五章数组和广义表习题_数据结构

习题五数组和广义表一、单项选择题)1.常对数组进行的两种基本操作是( D.查找与索引C.B.索引与修改建立与删除A. 查找与修改 K 个存储单元,二维数组中DataType A[m][n],2.对于 C 语言的二维数组每个数据元素占.( )a[i,j]的存储位置可由任意元素式确定 A.Loc[i,j]=A[m,n]+[(n+1)*i+j]*k B.Loc[i,j]=loc[0,0]+[(m+n)*i+j]*k C.Loc[i,j]=loc[0,0]+[(n+1)*i+j]*k D.Loc[i,j]=[(n+1)*i+j]*k 3.稀疏矩阵的压缩存储方法是只存储( ) A. 非零元素三元祖(i,j, aij)D. i,jC. aij B. 数组A[0..5,0..6]的每个元素占五个字节,将其按列优先次序存储在起始地址为10004. ( )的地址是A[5 ,5]的内存单元中,则元素。 A. 1175 B. 1180 C. 1205 D. 1210 A[N,N] 是对称矩阵,将下面三角(包括对角线)以行序存储到一维数组T[N (N+1)/2]5. 对应T[k] 的下标k是(中,则对任一上三角元素)。a[i][j] (i-1)/2+j(j-i)/2+1((j-1)/2+i i-1 )/2+1D. jB. jA. iC. i j 沿用数组r 存储静态链表,结点的next 域指向后继,工

作指针j 指向链中结点,使6. ( )链移动的操作为。 A. j=r[j].next B. j=j+1D. j=r[j]-> next C. j=j->next 对稀疏矩阵进行压缩存储目的是()。7. A.便于进行矩阵运算.便于输入和输出B .节省存储空间C.降低运算的时间复杂度D LS=((a,b,c),(d,e,f)),函数取出LS 中原子运用head 和tail e 的运算是已知广义表8. 。)( A. head(tail(LS)) B. tail(head(LS)) C. head(tail(head(tail(LS))) D. head(tail(tail(head(LS)))) 广义表((a,b,c,d),表尾是())的表头是()。9. (a,b,c,d(b,c,d)())D.C.A. aB. L=((a,b,c)),则L 的长度和深度分别为(设广义表)。10.和 3 1和和和3 2B. 1C. 1A. 1D. 211.下面说法不正确的是( )。 A. 广义表的表头总是一个广义表 B. 广义表的表尾总是一个广义表 C. 广义表难以用顺序存储结构 D.广义表可以是一个多层次的结构二、填空题 存储结构来存放数组___________1.通常采用。对二维数组可有两种存储方法:一种是以

数据结构 数组和广义表习题

第五章数组和广义表习题 一、选择题 1.已知广义表LS=((a,b,c),(d,e,f)),运用head和tail函数取出LS中原子e运算是。 A.head(tail(LS)) B.tail (head(LS)) C.head(tail(head(tail(LS)))) D. head(tail(tail(head(LS)))) 2.若广义表A满足head(A)=tail(A),则A为。 A.() B.(()) C.((),()) D.((),(),()) 3.广义表A=(a,b,(c,d),(e,(f,g))),则下面式子Head(Tail(Head(Tail(Tail(A)))))的值为。 A.() B.(d) C.c D.d 4.稀疏矩阵一般的压缩存储方法有两种。 A.二维数组和三维数组 B.三元组和散列表 C.三元组和十字链表 D.散列表和十字链表 5.已知矩阵A是一个对称矩阵,为了节省存储,将其下三角部分按行优先存放在一维数组B[1…n(n-1)/2]中,对下三角部分中任一元素aij(i>=j)在一维数组B的下标位置k值是。 A.i(i-1)/2+j-1 B. i(i-1)/2+j C. i(i+1)/2+j-1 D. i(i+1)/2+j 6.已知广义表L=((x,y,z),a,(u,t,w)),从L表中取出原子u的运算是。 A.head(tail(tail(L))) B.tail(head(head(tail(L)))) C.head(tail(head(tail(L)))) D.head(head(tail(tail(L)))) 7.广义表L=((a,b,c)),则L的长度和深度分别为。 A.1和1 B.1和3 C.1和2 D.2和3 8. tail (head(((a,b,c,d,e))))= 。 A.a B.c,d C. D.(b,c,d,e) 9.二维数组A[10…20,5…10]采用列序方式存储,每个数据元素占4个存储单元,且A[10,5]的存储地址是1000,则A[20,9]的地址是。 A.1216 B.1212 C.1256 D.1368 10.一个n*n的对称矩阵,如果以行或列为主序采用压缩存储,其容量为。 A.n*n B.n*n/2 C.(n+1)*n/2 D.(n+1)*(n+1)/2 11.数组SZ[-3…5,0…10]含有元素数目为。 A.88 B.99 C.80 D.90 12.二维数组M的成员是6个字符(每个字符占一个字节)组成的串,行下标i的范围从0到8,列下标j的范围从1到10,则存放M至少需要个字节;M的第8行和第5列共占个字节;若M按行优先方式存储,元素M[8][5]的起始地址与当M按列优先方式存储时的元素的起始地址一致。 (1)A.90 B.180 C.240 D.540 (2) A.108 B.114 C.54 D.60 (3) A.M[8][5] B.M[3][10] C.M[5][8] D.M[0][9] 二、填空题 1.需要压缩存储的矩阵有矩阵和矩阵。 2.广义表((a))的表头是,表尾是,表长是,表深是。 3.对于一个二维数组A[m][n],如果每个元素所占单元为L,若按行序为主序存储,则任一元素A[i][j]相对A[0][0]的地址为。 4.广义表(a,(a,b),d,e,((i,j),k))的长度是,深度是。 三、判断题 1.若一个广义表的表头为空表,则此广义表亦为空表。() 2.广义表是线性表的推广,是一类线性数据结构。() 1

相关文档
最新文档