数据结构经典易错习题.docx

上传人:b****6 文档编号:4376346 上传时间:2022-12-01 格式:DOCX 页数:28 大小:24.62KB
下载 相关 举报
数据结构经典易错习题.docx_第1页
第1页 / 共28页
数据结构经典易错习题.docx_第2页
第2页 / 共28页
数据结构经典易错习题.docx_第3页
第3页 / 共28页
数据结构经典易错习题.docx_第4页
第4页 / 共28页
数据结构经典易错习题.docx_第5页
第5页 / 共28页
点击查看更多>>
下载资源
资源描述

数据结构经典易错习题.docx

《数据结构经典易错习题.docx》由会员分享,可在线阅读,更多相关《数据结构经典易错习题.docx(28页珍藏版)》请在冰豆网上搜索。

数据结构经典易错习题.docx

数据结构经典易错习题

【例2.5】假设有n(n>1)个线性表顺序地存放在顺序表S[1..m]中,令F[i]和R[i]指

示第i个(1≤i≤n)表的第1个元素和最后1个元素在S中的位置,并设定R[i]

F[n+1]=m+1,如图2.2所示。

试写出实现下列要求的算法:

(1)在第i个表中的第j项后面插入1个元素,仅当整个[1..m]空间填满时,不允许进行

插入操作。

(2)删除第i个表中的第j个元素,要求在删除第j个元素后,该表仍为顺序存储的线性

表。

【解】本题实质上是将n个线性表(长度可能不相同)放在一个连续空间(长度为m),

来解决这些线性表的插入和删除问题。

(1)的算法如下:

voidins(i,j,x)

{

intp,k;

if(R[n]==m)

cout<<"上溢"<

else

{

for(p=n;p>=i+1;p--)//将i+1到n的线性表后移一个元素

{

for(k=R[p];k>=F[p];k--)//将第p个线性表后移一个元素

S[k+1]=S[k];

R[p]++;F[p]++;//第p个线性表的首尾元素位置均增1

}

for(p=R[i];p>=j+1;p--)

//将第i个线性表中的第j个位置起的元素均后移

S[p+1]=S[p];

S[p]=x;//在第i个线性表的第j个位置处存放x

R[p]++;//第p个线性表的R[p]增1

}

}

(2)的算法如下:

voiddel(i,j)

{

for(p=F[i]+j-1;p<=m;p++)//元素前移覆盖要删除的元素

S[p]=S[p+1];

for(p=i;p<=n;p++)//第i个及以后的线性表的R[i]值减1

R[p]--;

for(p=i+1;p<=n;p++)//第i+1个及以后的线性表的F[i]值减1

F[p]--;

}

 

【例2.6】设A=(a1,a2,⋯,am)和B=(b1,b2,⋯,bn)均为顺序表。

若n=m且ai=bi(i=1,⋯,n),则称A=B;若ai=bi(i=1,⋯,j)且aj+1

AB。

试编写一个比较A和B的算法,当AB时分别

输出-1、0或1。

【解】算法comp()的思想是先找出A和B中前面对应位置相同值的节点,i和j分别为A

和B中比较不相同元素的下标,然后根据i和j的情况得到A和B的比较结果。

实现本题功能的

程序如下:

#include

#include

#defineMaxLen50

typedefintElemType;

typedefElemTypesqlist[MaxLen];

intcreate(sqlista)

{

intn,s;

printf("pleaseinputthenumberofthelist\n");

scanf("%d",&n);

for(inti=0;i

{

printf("pleaseinputthe%delement\n",i+1);

scanf("%d",&s);

getchar();

a[i]=s;

}

returnn;

}

intcomp(sqlistA,intna,sqlistB,intnb)

{

inti=0,j=0;

while(A[i]==B[j]&&i

{

i++;

j++;

printf("hello\n");

}

if(i==na&&j==nb)

return0;

elseif(i==0&&j==0)

return1;

elseif(A[i]

return-1;

elsereturn1;

}

voidmain()

{

sqlistA,B;

inti,j,n;

i=create(A);

j=create(B);

n=comp(A,i,B,j);

switch(n)

{

case0:

printf("A=B\n");break;

case1:

printf("A>B\n");break;

case-1:

printf("A

}

}

设A和B是两个顺序表,其元素按从小到大的顺序排列。

编写一个将A和B中所有元素组成一个新的从小到大的有序顺序表C的算法,要求删除重复的元素。

intNewComine_1(sqlista,intna,sqlistb,intnb)//将两个按照由小到大顺序进行排列的链表进行合并,并将其中的相同元素删除

{

intm=na;

intn=nb;

inti=0;

intj=0;

intk=0;

sqlistc;

if(na==0&&nb==0)

exit(0);

if(na+nb>MaxLen)

exit(0);

while(i

{

if(a[i]>b[j])

{

c[k]=b[j];

k++;

j++;

}else

if(a[i]

{

c[k]=a[i];

k++;

i++;

}else

if(a[i]==b[j])

{

c[k]=a[i];

k++;

i++;

j++;

}

}

if(i

{

for(;i

{

c[k]=a[i];

k++;

}

}

if(j

{

for(;j

{

c[k]=b[j];

k++;

}

}

print(c,k);

returnna+nb;

}

【题8】己知在一维数组A[1:

m+n]中依次存放着两个顺序表(a1,a2,⋯,am)和(b1,

b2,⋯,bn),编写一个函数,将两个顺序表的位置互换,即把(b1,b2,⋯,bn)放到(a1,a2,⋯,

am)的前面。

本题的算法思想是:

由于顺序表的插入与删除操作需要大量的元素移动,所

用时间多,这里采用先将:

A:

(a1,a2,⋯,am,b1,b2,⋯,bn)

的所有元素逆置,即使之变成:

A:

(bn,⋯,b2,b1,am,⋯,a2,a1)

然后将(bn,⋯,b2,b1)逆置为(b1,b2,⋯,bn),将(am,⋯,a2,a1)逆置为(a1,a2,⋯,

am),这样便得到最终结果:

A:

(b1,b2,⋯,bn,a1,a2,⋯,am)

实现本题功能的程序如下:

#include"sq.cpp"

voidinvert(sqlistA,intlow,inthigh)

{

intm=(high-low+1)/2,i;//m为长度的一半

elemtypetemp;

for(i=0;i

{

temp=A[low+i];A[low+i]=A[high-i];A[high-i]=temp;

}

}

voidmain()

{

sqlistA;

intna,n;

na=create(A);

disp(A,na);

cout<<"输入n:

";

cin>>n;

invert(A,0,na-1);

disp(A,na);

invert(A,0,n-1);

disp(A,na);

invert(A,n,na-1);

disp(A,na);

}

本程序的一次执行结果如下(其中n指定第2组数序的长度):

创建一个顺序表

输入元素个数:

7

输入第1个元素值:

1

输入第2个元素值:

2

输入第3个元素值:

3

输入第4个元素值:

5

输入第5个元素值:

6

输入第6个元素值:

7

输入第7个元素值:

8

输出一个顺序表

1235678

输入n:

4l

输出一个顺序表

8765321

输出一个顺序表

5678321

输出一个顺序表

5678123

【题9】设有大小不等的n个数据组(n个数据组中数据的总数为m),顺序存放在空

间D内,每个数据占一个存储单元,数据组的首地址由数组S给出,如图2.3所示。

试编写将

新数据x插入到第i个数据组的末尾且属于第i个数据组的算法,插入后,空间区D和数组S的

相互关系仍保持正确。

图2.3数据组存储方式

voidins(i,x)

{

int*p,j;

if(i==n)//若i=n,则将x插入到最后

D[m+1]=x;

else

{

for(p=D+m+1;p>=S[n];p--)

//S[n]的元素均后移,D+m表示D[m]的地址

*p=*(p-1);

S[n]++;//将前一个位置的值放入后一个位置上

for(j=n-1;j>i;j--)//S[i+1]到S[n-1]的所有元素后移

{

for(p=S[j+1]-1;p>=S[j];p--)*p=*(p-1);

S[j]++;

}

*(S[i+1]-1)=x;

//将x放在S[i+1]前一个位置上,即S[i]的最后位置

}

}

 

【题11】设某机器表示的整数不超过5位十进制数字。

试设计一种表示任意长的整数

的数据结构,并利用你设计的数据结构,写出计算任意给定的两个整数之和的算法

将用户输入的正整数按各位数字存放在一个顺序表中,这样就变成了两个

顺序表中的数字相加。

实现本题功能的程序如下:

#include"sq.cpp"

intinput(sqlistA)

{

inti;

for(i=0;i

A[i]=0;

cout<<"输入一个正整数的各位(以-1结束)"<

i=0;

while

(1)

{

cin>>A[i];

if(A[i]<0)break;

i++;

}

returni;

}

voidoutput(sqlistA,intlow,inthigh)

//输出顺序表A中的A[low]到A[high]

{

inti;

for(i=low;i

cout<

cout<

}

voidmove(sqlistA,intna)//将A中存放的数字移到后面

{

inti;

for(i=0;i

A[MaxLen-i-1]=A[na-i-1];

}

intadd(sqlistA,intna,sqlistB,intnb)

//实现A,B相加,结果放在A中

{

intnc,i,j,length;

if(na>nb)nc=na;

elsenc=nb;

move(A,na);

move(B,nb);

for(i=MaxLen-1;i>=MaxLen-nc;i--)

{

j=A[i]+B[i];

if(j>9)

{

A[i-1]=A[i-1]+1;

A[i]=j-10;

}

elseA[i]=j;

if(i==MaxLen-nc)

{

if(j>9)

{

A[i-1]=1;

length=nc+1;

}

elselength=nc;

}

}

returnlength;

}

voidmain()

{

sqlistA,B;

intna,nb,nc;

na=input(A);

nb=input(B);

cout<<"整数A:

";

output(A,0,na);

cout<<"整数B:

";

output(B,0,nb);

nc=add(A,na,B,nb);

cout<<"相加:

";

output(A,MaxLen-nc,MaxLen);

}

本程序的一次执行结果如下:

输入一个正整数的各位(以-1结束)

9999999999999-1

输入一个正整数的各位(以-1结束)

6666666666666-1

整数A:

9999999999999

整数B:

6666666666666

相加:

166********665

【例3.2】设A=(a1,a2,⋯,an)和B=(b1,b2,⋯,bm)是两个不带哨兵的单链表。

n=m且ai=bi(i=1,⋯,n),则称A=B;若ai=bi(i=1,⋯,j)且aj+1

在其他情况下均称A>B。

试编写一个比较A和B的算法,当AB时分别输出-1、

0或1。

intcomp(LA,LB)//判断2个表的大小

{

Lla,lb;

if(A==NULL||A->next==NULL||B==NULL||B->next==NULL)

exit(0);

la=A;

lb=B;

la=A->next;

lb=B->next;

while(la->i==lb->i)

{

la=la->next;

lb=lb->next;

if(la==NULL&&lb!

=NULL)

{

return-1;

}

if(lb==NULL&&la!

=NULL)

{

return1;

}

if(NULL==la&NULL==lb)

return0;

}

if(la==A->next&&lb==B->next)

return1;

elseif(la->ii)

return-1;

elsereturn1;

}

【例3.6】假设有两个按元素值递增有序排列的单链表A和B,编写一个算法将A和B

归并成一个按元素值递增有序排列的单链表C(相同值的元素只归并一次),并要求利用原单

链表(A和B)的节点空间存放单链表C。

LCombineList(Ll1,Ll2)//将两个按由小到大递增的链表进行排序

{

Lp1,p2,p3,l3;

if(l1==NULL||l1->next==NULL||l2==NULL||l2->next==NULL)

exit(0);

l3=(L)malloc(sizeof(List));

if(NULL==l3)

exit(0);

p1=l1->next;

p2=l2->next;

p3=l3;

while(p1!

=NULL&&p2!

=NULL)

{

if(p1->i>p2->i)

{

p3->next=p2;

p3=p2;

if(p2->next==NULL)

{

p2=p2->next;

break;

}else

p2=p2->next;

}

if(p1->ii)

{

p3->next=p1;

p3=p1;

if(p1->next==NULL)

{

p1=p1->next;

break;

}else

p1=p1->next;

}

if(p1->i==p2->i)

{

p3->next=p1;

p3=p1;

if(NULL==p1->next||NULL==p2->next)

{

p1=p1->next;

p2=p2->next;

break;

}else

p1=p1->next;

p2=p2->next;

}

}

if(p1!

=NULL)

{

p3->next=p1;

}

if(p2!

=NULL)

{

p3->next=p2;

}

returnl3;

}

【例3.10】设计循环单链表结构并实现循环单链表的基本操作。

【解】不带哨兵节点的循环单链表结构如图3.6所示。

其中h为头节点指针,亦简称

为头指针。

图3.6不带哨兵节点的循环单链表结构

实现本题功能的clink.cpp文件如下(后面的有关循环单链表的算法设计都使用其中的

函数,其中的循环单链表都是不带哨兵节点的循环单链表):

#include

#include

typedefintelemtype;//定义数据域的类型

typedefstructlinknode//定义节点类型

{

elemtypedata;

structlinknode*next;

}nodetype;

nodetype*cyccreate()

//创建循环单链表,用户输入各节点data域之值,0表示输入结束

{

elemtyped;

nodetype*h=NULL,*s,*t=NULL;

inti=1;

cout<<"建立一个循环单链表"<

while

(1)

{

cout<<"输入第"<

";

cin>>d;

if(d==0)break;//以0表示输入结束

if(i==1)//建立第一个节点

{

h=(nodetype*)malloc(sizeof(nodetype));

h->data=d;h->next=NULL;t=h;

}

else//建立其余节点

{

s=(nodetype*)malloc(sizeof(nodetype));

s->data=d;s->next=NULL;t->next=s;

t=s;//t始终指向生成的循环单链表的最后一个节点

}

i++;

}

if(t!

=NULL)t->next=h;

//将最后一不为NULL的节点的next置为h

returnh;

}

voidcycdisp(nodetype*h)

//输出由h指向的循环单链表的所有data域之值

{

nodetype*p=h;

cout<<"输出一个循环单链表:

"<

if(p==NULL)

{

cout<<"空表"<

}

while(p->next!

=h)

{

cout<data<<"";p=p->next;

}

cout<data<<""<

}

intcyclen(nodetype*h)//返回循环单链表的长度

{

inti=1;

nodetype*p=h;

if(p==NULL)return0;

while(p->next!

=h)

{

p=p->next;i++;

}

returni;

}

nodetype*cycfind(nodetype*h,inti)

//返回第i个节点的指针

{

nodetype*p=h;

intj=1;

if(i>cyclen(h)||i<=0)returnNULL;//i值上溢或下溢

else

{

if(i==1)returnp;//i=1时返回头指针

while(p->next!

=h&&j

{

j++;p=p->next;

}

returnp;

}

}

nodetype*cycins(nodetype*h,inti,elemtypex)

//在循环单链表head中第i个节点(i>=0)之后插入一个data域为x的节点

{

nodetype*p,*s,*r;

s=(nodetype*)malloc(sizeof(nodetype));//创建节点s

s->data=x;s->next=NULL;

if(i==0)//i=0:

s作为该循环单链表的第一个节点

{

r=h;

while(r->next!

=h)r=r->next;//r为最后节点的指针

s->next=h;h=s;r->next=h;//修改r的next域

}

else

{

p=cycfind(h,i);//查找第i个节点,并由p指向该节点

if(p!

=NULL)//将s插入到p之后

{

s->next=p->next;p->next=s;

}

elsecout<<"输入的i值不正确"<

}

returnh;

}

nodetype*cycdel(nodetype*h,inti)//删除第i个节点

{

nodetype*p=h,*s,*r;

intj=1;

if(i==1)//删除第1个节点

{

r=h;

while(r->next!

=h)r=r->next;//r为最后节点的指针

h=h->next;r->next=h;//重置r的next域

free(p);

}

else

{

p=cycfind(h,i-1);//查找第i-1个节点,并由p指向该节点

if(p!

=NULL&&p->next!

=h)//若存在要删除的节点

{

s=p->next;//s指向要删除的节点

p->next=s->next;free(s);

}

elsecout<<"输入的i值不正确"<

}

returnh;

}

voidcycdispose(nodetype*h)//释放循环单链表的所有节点占用的空间

{

nodetype*pa=h,*pb;

if(pa!

=NULL)

{

pb=pa->next;

if(pb==h)//只有一个节点的情况

free(pa);

else

{

while(pb->next!

=h)//有两个及以上节点的情况

{

free(pa);pa=pb;pb=pb->next;

}

free(pa);

}

}

}

【例3.11】假设在长度大于1的循环单链表中,既无头节点也无头指针,p为指向该

链表中某个节点的指针。

设计一个算法删除该节点的前驱节点。

【解】本题利用循环单链表的特点,通过p指针循环找到其前驱节点q及q的前驱节点

r,然后将其删除。

实现本题功能的程序如下:

#include"clink.cpp"

nodetype*delprev(nodetype*p)

{

nodetype*r=p,*q=r->next;

while(q->next!

=p)//查找p节点的前驱节点q,r指向q的前驱节点

{

r=r->next;q=r->next;

}

r->next=p;//删除

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > PPT模板 > 国外设计风格

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1