;
//删除第一个元素
for(j=;j>=i+1;j--)[j-i]=[j];
;
}
returnOK;
}
设顺序表va中的数据元素递增有序。
试写一算法,将x插入到顺序表的适当位置上,以保持该表的有序性。
解:
StatusInsertOrderList(SqList&va,ElemTypex)
/
{
//在非递减的顺序表va中插入元素x并使其仍成为顺序表的算法
inti;
if==return(OVERFLOW);
for(i=;i>0,x<[i-1];i--)
[i]=[i-1];
[i]=x;
++;
returnOK;
}
…
设
和
均为顺序表,
和
分别为
和
中除去最大共同前缀后的子表。
若
空表,则
;若
=空表,而
空表,或者两者均不为空表,且
的首元小于
的首元,则
;否则
。
试写一个比较
,
大小的算法。
试写一算法在带头结点的单链表结构上实现线性表操作Locate(L,x);
试写一算法在带头结点的单链表结构上实现线性表操作Length(L)。
已知指针ha和hb分别指向两个单链表的头结点,并且已知两个链表的长度分别为m和n。
试写一算法将这两个链表连接在一起,假设指针hc指向连接后的链表的头结点,并要求算法以尽可能短的时间完成连接运算。
请分析你的算法的时间复杂度。
已知指针la和lb分别指向两个无头结点单链表中的首元结点。
下列算法是从表la中删除自第i个元素起共len个元素后,将它们插入到表lb中第i个元素之前。
试问此算法是否正确若有错,请改正之。
StatusDeleteAndInsertSub(LinkedListla,LinkedListlb,inti,intj,intlen)
~
{
if(i<0||j<0||len<0)returnINFEASIBLE;
p=la;k=1;
while(knext;k++;}
q=p;
while(k<=len){q=q->next;k++;}
s=lb;k=1;
while(knext;k++;}
s->next=p;q->next=s->next;
returnOK;
·
}
试写一算法,在无头结点的动态单链表上实现线性表操作Insert(L,i,b),并和在带头结点的动态单链表上实现相同操作的算法进行比较。
试写一算法,实现线性表操作Delete(L,i),并和在带头结点的动态单链表上实现相同操作的算法进行比较。
已知线性表中的元素以值递增有序排列,并以单链表作存储结构。
试写一高效的算法,删除表中所有值大于mink且小于maxk的元素(若表中存在这样的元素),同时释放被删结点空间,并分析你的算法的时间复杂度(注意,mink和maxk是给定的两个参变量,它们的值可以和表中的元素相同,也可以不同)。
同题条件,试写一高效的算法,删除表中所有值相同的多余元素(使得操作后的线性表中所有元素的值均不相同),同时释放被删结点空间,并分析你的算法的时间复杂度。
试写一算法,实现顺序表的就地逆置,即利用原表的存储空间将线性表
逆置为
。
~
试写一算法,对单链表实现就地逆置。
设线性表
,
,试写一个按下列规则合并A,B为线性表C的算法,即使得
当
时;
当
时。
线性表A,B和C均以单链表作存储结构,且C表利用A表和B表中的结点空间构成。
注意:
单链表的长度值m和n均未显式存储。
假设有两个按元素值递增有序排列的线性表A和B,均以单链表作存储结构,请编写算法将A表和B表归并成一个按元素值递减有序(即非递增有序,允许表中含有值相同的元素)排列的线性表C,并要求利用原表(即A表和B表)的结点空间构造C表。
假设以两个元素依值递增有序排列的线性表A和B分别表示两个集合(即同一表中的元素值各不相同),现要求另辟空间构成一个线性表C,其元素为A和B中元素的交集,且表C中的元素有依值递增有序排列。
试对顺序表编写求C的算法。
…
要求同题。
试对单链表编写求C的算法。
对题的条件作以下两点修改,对顺序表重新编写求得表C的算法。
(1)假设在同一表(A或B)中可能存在值相同的元素,但要求新生成的表C中的元素值各不相同;
(2)利用A表空间存放表C。
对题的条件作以下两点修改,对单链表重新编写求得表C的算法。
(1)假设在同一表(A或B)中可能存在值相同的元素,但要求新生成的表C中的元素值各不相同;
(2)利用原表(A表或B表)中的结点构成表C,并释放A表中的无用结点空间。
\
已知A,B和C为三个递增有序的线性表,现要求对A表作如下操作:
删去那些既在B表中出现又在C表中出现的元素。
试对顺序表编写实现上述操作的算法,并分析你的算法的时间复杂度(注意:
题中没有特别指明同一表中的元素值各不相同)。
要求同题。
试对单链表编写算法,请释放A表中的无用结点空间。
假设某个单向循环链表的长度大于1,且表中既无头结点也无头指针。
已知s为指向链表中某个结点的指针,试编写算法在链表中删除指针s所指结点的前驱结点。
已知有一个单向循环链表,其每个结点中含三个域:
pre,data和next,其中data为数据域,next为指向后继结点的指针域,pre也为指针域,但它的值为空,试编写算法将此单向循环链表改为双向循环链表,即使pre成为指向前驱结点的指针域。
已知由一个线性链表表示的线性表中含有三类字符的数据元素(如:
字母字符、数字字符和其他字符),试编写算法将该线性表分割为三个循环链表,其中每个循环链表表示的线性表中均只含一类字符。
#
假设在算法描述语言中引入指针的二元运算“异或”,若a和b为指针,则a⊕b的运算结果仍为原指针类型,且
a⊕(a⊕b)=(a⊕a)⊕b=b
(a⊕b)⊕b=a⊕(b⊕b)=a
则可利用一个指针域来实现双向链表L。
链表L中的每个结点只含两个域:
data域和LRPtr域,其中LRPtr域存放该结点的左邻与右邻结点指针(不存在时为NULL)的异或。
若设指针指向链表中的最左结点,指向链表中的最右结点,则可实现从左向右或从右向左遍历此双向链表的操作。
试写一算法按任一方向依次输出链表中各元素的值。
采用题所述的存储结构,写出在第i个结点之前插入一个结点的算法。
采用题所述的存储结构,写出删除第i个结点的算法。
设以带头结点的双向循环链表表示的线性表
。
试写一时间复杂度O(n)的算法,将L改造为
。
设有一个双向循环链表,每个结点中除有pre,data和next三个域外,还增设了一个访问频度域freq。
在链表被起用之前,频度域freq的值均初始化为零,而每当对链表进行一次Locate(L,x)的操作后,被访问的结点(即元素值等于x的结点)中的频度域freq的值便增1,同时调整链表中结点之间的次序,使其按访问频度非递增的次序顺序排列,以便始终保持被频繁访问的结点总是靠近表头结点。
试编写符合上述要求的Locate操作的算法。
.
已知稀疏多项式
,其中
,
,
。
试采用存储量同多项式项数m成正比的顺序存储结构,编写求
的算法(
为给定值),并分析你的算法的时间复杂度。
采用题给定的条件和存储结构,编写求
的算法,将结果多项式存放在新辟的空间中,并分析你的算法的时间复杂度。
试以循环链表作稀疏多项式的存储结构,编写求其导函数的方法,要求利用原多项式中的结点空间存放其导函数多项式,同时释放所有无用结点。
试编写算法,将一个用循环链表表示的稀疏多项式分解成两个多项式,使这两个多项式中各自仅含奇次项或偶次项,并要求利用原链表中的结点空间构成这两个链表。
第3章栈和队列
若按教科书节中图(b)所示铁道进行车厢调度(注意:
两侧铁道均为单向行驶道),则请回答:
(1)如果进站的车厢序列为123,则可能得到的出站车厢序列是什么
(2)如果进站的车厢序列为123456,则能否得到435612和135426的出站序列,并请说明为什么不能得到或者如何得到(即写出以‘S’表示进栈和以‘X’表示出栈的栈操作序列)。
{
简述栈和线性表的差别。
写出下列程序段的输出结果(栈的元素类型SElemType为char)。
voidmain()
{
StackS;
charx,y;
InitStack(S);
x=‘c’;y=‘k’;
Push(S,x);Push(S,‘a’);Push(S,y);
<
Pop(S,x);Push(S,‘t’);Push(S,x);
Pop(S,x);Push(S,‘s’);
while(!
StackEmpty(S)){Pop(S,y);printf(y);}
printf(x);
}
简述以下算法的功能(栈的元素类型SElemType为int)。
(1)statusalgo1(StackS)
{
inti,n,A[255];
|
n=0;
while(!
StackEmpty(S)){n++;Pop(S,A[n]);}
for(i=1;i<=n;i++)Push(S,A[i]);
}
(2)statusalgo2(StackS,inte)
{
StackT;intd;
InitStack(T);
while(!
StackEmpty(S)){
Pop(S,d);
|
if(d!
=e)Push(T,d);
}
while(!
StackEmpty(T)){
Pop(T,d);
Push(S,d);
}
}
假设以S和X分别表示入栈和出栈的操作,则初态和终态均为空栈的入栈和出栈的操作序列可以表示为仅由S和X组成的序列。
称可以操作的序列为合法序列(例如,SXSX为合法序列,SXXS为非法序列)。
试给出区分给定序列为合法序列或非法序列的一般准则,并证明:
两个不同的合法(栈操作)序列(对同一输入序列)不可能得到相同的输出元素(注意:
在此指的是元素实体,而不是值)序列。
:
试证明:
若借助栈由输入序列12…n得到的输出序列为
(它是输入序列的一个排列),则在输出序列中不可能出现这样的情形:
存在着i<
<
。
按照四则运算加、减、乘、除和幂运算(↑)优先关系的惯例,并仿照教科书节例3-2的格式,画出对下列算术表达式求值时操作数栈和运算符栈的变化过程:
A-B×C/D+E↑F
试推导求解n阶梵塔问题至少要执行的move操作的次数。
试将下列递推过程改写为递归过程。
voidditui(intn)
{
inti;
、
i=n;
while(i>1)
cout<}
试将下列递归过程改写为非递归过程。
voidtest(int&sum)
{
intx;
cin>>x;
/
if(x==0)sum=0;
else
{
test(sum);
sum+=x;
}
cout<}
简述队列和堆栈这两种数据类型的相同点和差异处。
…
写出以下程序段的输出结果(队列中的元素类型QElemType为char)。
voidmain()
{
QueueQ;
InitQueue(Q);
charx=‘e’,y=‘c’;
EnQueue(Q,‘h’);
EnQueue(Q,‘r’);
EnQueue(Q,y);
)
DeQueue(Q,x);
EnQueue(Q,x);
DeQueue(Q,x);
EnQueue(Q,‘a’);
While(!
QueueEmpty(Q))
{
DeQueue(Q,y);
cout<}
cout<:
}
简述以下算法的功能(栈和队列的元素类型均为int)。
voidalgo3(Queue&Q)
{
StackS;
intd;
InitStack(S);
while(!
QueueEmpty(Q))
{
@
DeQueue(Q,d);
Push(S,d);
}
while(!
StackEmpty(S))
{
Pop(S,d);
EnQueue(Q,d);
}
}
&
若以1234作为双端队列的输入序列,试分别求出满足以下条件的输出序列:
(1)能由输入受限的双端队列得到,但不能由输出受限的双端队列得到的输出序列。
(2)能由输出受限的双端队列得到,但不能由输入受限的双端队列得到的输出序列。
(3)既不能由输入受限的双端队列得到,也不能由输出受限的双端队列得到的输出序列。
假设以顺序存储结构实现一个双向栈,即在一维数组的存储空间中存在着两