数据结构上机例题及答案Word文档格式.docx
- 文档编号:19160597
- 上传时间:2023-01-04
- 格式:DOCX
- 页数:35
- 大小:25.03KB
数据结构上机例题及答案Word文档格式.docx
《数据结构上机例题及答案Word文档格式.docx》由会员分享,可在线阅读,更多相关《数据结构上机例题及答案Word文档格式.docx(35页珍藏版)》请在冰豆网上搜索。
{if(t==0)
p=p->
t=1;
next=p->
p->
next=s->
s=p;
t=0;
return(hb);
2.5设线性表中的数据元素是按值非递减有序排列的,试以不同的存储结构,编写一算法,将x插入到线性表的适当位置上,以保持线性表的有序性。
⑴顺序表;
解:
本题的算法思想是:
先找到适当的位置,然后后移元素空出一个位置,再将x插入,并返回向量的新长度。
实现本题功能的函数如下:
intinsert(vectorA,intn,ElemTypex)/*向量A的长度为n*/
{inti,j;
if(x>
=A[n-1])A[n]=x/*若x大于最后的元素,则将其插入到最后*/else
{i=0;
while(x>
=A[i])i++;
/*查找插入位置i*/
for(j=n-1;
j>
=i;
j--)A[j+1]=A[j];
/*移出插入x的位置*/A[i]=x;
n++;
/*将x插入,向量长度增1*/
}
returnn;
⑵单链表。
本题算法的思想是先建立一个待插入的结点,然后依次与链表中的各结点的数据域比较大小,找到插入该结点的位置,最后插入该结点。
node*insertorder(head,x)
node*head;
ElemTypex;
{
node*s,*p,*q;
s=(node*)malloc(sizeof(node));
/*建立一个待插入的结点*/
data=x;
if(head==NULL||x<
head->
data)/*若单链表为空或x小于第一个结点的date域*/
next=head;
/*则把s结点插入到表头后面*/
head=s;
else
{q=head;
/*为s结点寻找插入位置,p指向待比较的结点,q指向p的前驱结点*/
p=q->
while(p!
=NULL&
x>
data)/*若x小于p所指结点的data域值*/
data)/*则退出while循环*/
q=p;
/*将s结点插入到q和p之间*/
q->
return(head);
2.6假设有A和B分别表示两个递增有序排列的线性表集合(即同一表中元素值各不相同),求A和B的交集C,表C中也依值递增有序排列。
试以不同的存储结构编写求得C的算法。
voidSqList_Intersect_True(SqList&
A,SqListB)//求元素递增排列的线性表A和B的元素的交集并存回A中
{
i=1;
j=1;
k=0;
while(A.elem[i]&
B.elem[j])
if(A.elem[i]<
B.elem[j])i++;
elseif(A.elem[i]>
B.elem[j])j++;
elseif(A.elem[i]!
=A.elem[k])
A.elem[++k]=A.elem[i];
//当发现了一个在A,B中都存在的元素
i++;
j++;
//且C中没有,就添加到C中
}//while
while(A.elem[k])A.elem[k++]=0;
}//SqList_Intersect_True
⑵单链表。
单链表
chnode*or(chnode*head1,chnode*head2)
{chnode*p1,*p2,*q2,*h,*p;
h=p=malloc(sizeof(chnode));
p1=head1->
while(p1)
{p2=head2;
q2=p2->
while((q2->
=p1->
data)&
q2)
{p2=q2;
q2=q2->
if(p1->
data==q2->
data)
p2->
next=q2->
if(q2)
{while(p->
next)
next=q2;
p=q2;
q2->
p1=p1->
return(h);
2.7设计一个算法求两个递增有序排列的线性表A和B的差集。
(每个单链表中不存在重复的元素)
提示:
即在A中而不在B中的结点的集合。
typedefintelemtype;
typedefstructlinknode
elemtypedata;
structlinknode*next;
}nodetype;
nodetype*subs(nodetype*heada,nodetype*headb)
nodetype*p,*q,*r,*s;
s=(nodetype*)malloc(sizeof(nodetype));
next=heada;
heada=s;
p=heada->
next;
r=heada;
r->
next=NULL;
q=headb;
while(q!
q->
=p->
data)q=q->
if(q!
s=p->
free(p);
p=s;
else
next=p;
r=p;
s=heada;
heada=heada->
free(s);
returnheada;
2.8设有线性表A=(a1,a2,...,am),B=(b1,b2,...,bn)。
试写一合并A、B为线性表C的算法,使得
(a1,b1,...,am,bm,bm+1,...,bn)当m≤n时
C={
(a1,b1,...,an,bn,an+1,...,am)当m>n时
A、B和C均以单链表作存储结构,且C表利用A和B中结点空间。
假设A,B和C链表分别具有头结点的指针a,b和c。
node*link(a,b)
node*a,*b;
node*r,*s,*p,*q,*c;
c=(node*)malloc(sizeof(node));
/*建立一个头结点*/
r=c;
p=a;
q=b;
=NULL||q!
=NULL)
if(p!
=NULL)/*如果A链表还存在可取的结点,则复制一个同样的结点链接到C中*/
data=p->
data;
r=s;
=NULL)/*如果B链表还存在可取的结点,则复制一个同样的结点链接到C中*/
data=q->
q=q->
s=c;
c=c->
/*删除头结点*/
free(s);
return(c);
2.9试用两种线性表的存储结构来解决约瑟夫问题。
设有n个人围坐在圆桌周围,现从第s个人开始报数,数到第m个人出列,然后从出列的下一个人重新开始报数,数到第m个人又出列,…,如此重复直到所有的人全部出列为止。
例如当n=8,m=4,s=1,得到的新序列为:
4,8,5,2,1,3,7,6。
写出相应的求解算法。
先构造一个循环链表
nodetype*crea(intn)
{nodetype*s,*r,*h;
intI;
for(i=1;
i<
=n;
i++)
{s=(nodetype*)malloc(sizeof(nodetype));
data=I;
if(i==1)h=s;
elser->
next=h;
returnh;
voidjese(nodetype*h,intm)
{nodetype*p=h,*q;
while(p->
=p)
{for(i=1;
m-1;
if(p->
{q=p->
printf(“%d”,q->
data);
next=q->
free(q);
printf(“%d”,p->
2.10已知单链表中的数据元素含有三类字符(即:
字母字符、数字字符和其它字符),试编写算法构造三个环形链表,使每个环形链表中只含同一类的字符,且利用原表中的结点空间作为这三个表的结点空间,头结点可另辟空间。
voidsplit(nodetype*ha,nodetype*hb,nodetype*hc)
{charc;
nodetype*ra,*rb,*rc,*p=ha->
ra=ha;
ra->
rb=hb;
rb->
rc=hc;
rc->
while(p!
=ha)
{c=p->
if((c>
=’a’&
c<
=’z’)||(c>
=’A’&
=’Z’))
{ra->
ra=p;
elseif(c>
=’0’&
=’9’)
{rb->
rb=p;
else
{rc->
rc=p;
ra->
next=ha;
next=hb;
next=hc;
2.11假设有一个循环链表的长度大于1,且表中既无头结点也无头指针。
已知p为指向链表中某结点的指针,试编写算法在链表中删除结点p的前趋结点。
nodetype*delprev(nodetype*p)
{nodetype*r=p,*q=r->
while(q->
{r=r->
q=r->
r->
return(p);
2.12假设有一个单向循环链表,其结点含三个域:
pre、data和next,每个结点的pre值为空指针,试编写算法将此链表改为双向环形链表。
分析:
在遍历单链表时,可以利用指针记录当前访问结点和其前驱结点。
知道了当前访问结点的前驱结点位置,就可以给当前访问结点的前驱指针赋值。
这样在遍历了整个链表后,所有结点的前驱指针均得到赋值。
Typedefstructlnode
{elemtypedata;
structlnodepre,next;
}lnode,*linklist;
voidsingletodouble(linklisth)
{linklistpre,p;
pre=h;
while(p!
=h)
pre=pre;
pre=p;
2.13设有一个二维数组A[m][n],假设A[0][0]存放位置在644(10),A[2][2]存放位置在676(10),每个元素占一个地址空间,求A[3][3](10)存放在什么位置?
分析根据二维数组的地址计算公式:
LOC(i,j)=LOC(0,0)+[n*i+j]*s,首先要求出数组第二维的长度,即n值。
解因为LOC(2,2)=LOC(0,0)+2*n+2=644+2*n+2=676
所以n=(676-2-644)/2=15
LOC(3,3)=LOC(0,0)+3*15+3=644+45+3=692
2.14设稀疏矩阵采用十字链表结构表示。
试写出实现两个稀疏矩阵相加的算法。
依题意,C=A+B,则C中的非零元素cij只可能有3种情况:
或者是aij+bij,或者是aij(bij=0)或者是bij(aij=0)。
因此,当B加到A上时,对A矩阵的十字链表来说,或者是改变结点的val域值(a+b≠0),或者不变(b=0),或者插入一个新结点(a=0),还可能是删除一个结点(aij+bij=0)。
整个运算可从矩阵的第一行起逐行进行。
对每一行都从行表头出发分别找到A和B在该行中的第一个非零元素结点后开始比较,然后按4种不同情况分别处理(假设pa和pb分别指向A和B的十字链表中行值相同的两个结点):
若pa->
col=pb->
col且pa->
val+pb->
val≠0,则只要将aij+bij的值送到pa所指结点的值域中即可。
(2)若pa->
val=0,则需要在A矩阵的十字链表中删除pa所指结点,此时需改变同一行中前一结点的right域值,以及同一列中前一结点的down域值。
(3)若pa->
col<
pb->
col≠0(即不是表头结点),则只需要将pa指针往右推进一步,并重新加以比较。
(4)若pa->
col>
col或pa->
col=0,则需要在A矩阵的十字链表中插入一个值为bij的结点。
实现本题功能的程序如下:
#include<
stdio.h>
#defineMAX100
structmatnode*createmat(structmatnode*h[])
/*h是建立的十字链表各行首指针的数组*/
{intm,n,t,s,i,r,c,v;
structmatnode*p,*q;
printf("
行数m,列数n,非零元个数t:
"
);
scanf("
%d,%d,%d"
,&
m,&
n,&
t);
p=(structmatnode*)malloc(sizeof(structmatnode));
h[0]=p;
row=m;
col=n;
s=m>
n?
m:
n;
/*s为m、n中的较大者*/
for(i=1;
=s;
i++)
h[i]=p;
h[i-1]->
tag.next=p;
row=p->
col=0;
down=p->
right=p;
h[s]->
tag.next=h[0];
=t;
\t第%d个元素(行号r,列号c,值v):
,i);
r,&
c,&
v);
row=r;
col=c;
tag.val=v;
q=h[r];
while(q->
right!
=h[r]&
right->
c)
q=q->
right;
right=q->
q=h[c];
while(q->
down!
=h[c]&
down->
row<
r)
down;
down=q->
down=p;
return(h[0]);
voidprmat(structmatnode*hm)
\n按行表输出矩阵元素:
\n"
row=%dcol=%d\n"
,hm->
row,hm->
col);
p=hm->
tag.next;
=hm)
q=p->
=q)
\t%d,%d,%d\n"
,q->
row,q->
col,q->
tag.val);
structmatnode*colpred(i,j,h)
/*根据i(行号)和j(列号)找出矩阵第i行第j列的非零元素在十字链表中的前驱结点*/
inti,j;
structmatnode*h[];
structmatnode*d;
d=h[j];
while(d->
col!
=0&
d->
i)
d=d->
return(d);
structmatnode*addmat(ha,hb,h)
structmatnode*ha,*hb,*h[];
structmatnode*p,*q,*ca,*cb,*pa,*pb,*qa;
if(ha->
row!
=hb->
row||ha->
col)
printf("
两个矩阵不是同类型的,不能相加\n"
exit(0);
ca=ha->
cb=hb->
do
pa=ca->
pb=cb->
qa=ca;
while(pb->
=0)
if(pa->
col&
pa->
qa=pa;
pa=pa->
elseif(pa->
col||pa->
col==0)
*p=*pb;
right=pa;
qa->
qa=p;
q=colpred(p->
row,
col,h);
pb=pb->
pa->
tag.val+=pb->
tag.val;
tag.val==0)
right=pa->
q=colpred(pa->
down=pa->
free(pa);
elseqa=pa;
ca=ca->
cb=cb->
}while(ca->
row==0);
main()
structmatnode*hm,*hm1,*hm2;
structmatnode*h[MAX],*h1[MAX];
第一个矩阵:
hm1=createmat(h);
第二个矩阵:
hm2=createmat(h1);
hm=addmat(hm1,hm2,h);
prmat(hm);
第二章上机内容
1.设计一个程序,生成两个按值非递减有序排列的线性表LA和LB,再将LA和LB归并为一个新的线性表LC,且LC中的数据仍按值非递减有序排列,输出线性表LA,LB,LC。
#include“stdio.h”
#include“alloc.h”
typedefstructnode
chardata;
structnode*next;
}listnode;
typedefstructnode*link
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 数据结构 上机 例题 答案