队列1
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
学习有关队列的知识,完成P1194、P1195
队列
在日常生活中有许多“队列“的例子,如车站售票口买票的队伍,排在前面的人先买到票离开队伍,后来的人则加入队伍的末尾等候买票;其特点是“先进先出”(First In First Out)或“后进后出”(Last In Last Out)。
“队列”是在一端插入,另一端删除的特殊的线性表。进行删除的一端称为“队首”,进行插入的一端称为“队尾”(如下图);插入也叫入队,删除则叫出队;在对队列进行操作时,一定要注意一头一尾。
队列可以用数组Q[1…m]来存储,数组的上界m即是队列所容许的最大容量。在队列的运算中需设两个指针:
f:队首指针,指向实际队头元素的前一个位置
r:队尾指针,指向实际队尾元素所在的位置
队列中拥有的元素个数为:L=r-f。一般情况下,两个指针的初值设为0,这时队列为空,没有元素。
1. 队列的定义
2.
const
m=队列元素的上限;
type
equeue= array [1..m] of qtype; {队列的类型定义}
var
q:equeue; {队列}
f , r : integer; {队首指针与队尾指针}
3. 入队过程ADD(q,x,r)——在队列的尾端插入元素x
4.
procedure ADD(var q: equeue ;x:qtype ;var r:integer);begin
if r=m then writeln(‘overflow’) {队列满上溢} else begin
r:=r+1;
q[r]:=x;
end{else}
end;{add}
出队过程DEL(q,y,f,r)——取出q队列的队首元素y
procedure DEL(var q:equeue;var y:qtype;var f,r:integer);begin
if f=r then writeln(‘underflow’) {队列空下溢} else begin
f:=f+1;
y:=q[f];
end;{else}
end;{del}
例1、有N张牌,记为1,2,...,N,应当怎样排放,才能使:打开第一张是1,然后把两张依次放在末尾;打开上面一张,刚好是2,再依次打开上面一张,刚好是3;如此继续下去,直至打开最后一张是N。写一个程序解决这个问题。
解:Pascal程序:
Program lt7_2_1;
var a,b:array[1..10000] of integer;
i,j,t,h,n:integer;
begin
readln(n);
for i:=1 to n do a[i]:=i;
a[1]:=1;h:=2;t:=n;b[1]:=1;
for i:=2 to n do
begin
for j:=1 to i do
begin
inc(t);a[t]:=a[h];inc(h);
end;
b[a[h]]:=i;inc(h);
end;
for i:=1 to n do
write(b[i]:5);
end.
分析:这是一个典型队列的例子,请大家仔细体会在队列操作过程中头指针和尾指针的变化。
例2、集合的前N个元素:编一个程序,按递增次序生成集合M的最小的N个数,M的定义如下:
(1)数1属于M;
(2)如果X属于M,则Y=2*X+1和Z=3*X+1也属于M;
(3)此外再没有别的数属于M。
解:Pascal程序:
Program lt7_2_1;
var a,b:array[1..1000] of integer;
x,ha,hb,t,total,n:integer;
begin
assign(output,'data4.out');rewrite(output);
readln(n);
x:=1;a[1]:=1;
ha:=1;hb:=1;t:=0;total:=1;
while total<=n do
begin
write(x,' ');
inc(t);
a[t]:=2*x+1;b[t]:=3*x+1;
if a[ha]>b[hb] then begin
x:=b[hb];inc(hb);
end
else begin
x:=a[ha];
if a[ha]=b[hb] then inc(hb);
inc(ha);
end;
inc(total);
end;
close(output);
end.
分析:可以用两个队列来存放Y和Z中的数,分别用数组a和数组b存放。然后递推求出第N项,方法如下:
(1)令ha和hb分别为队列a和队列b的头指针,它们的尾指针为t。初始时,X=1,ha=hb=t=1;
(2)将2*x+1和3*x+1分别放入队列a和队列b的队尾,尾指针加1。即: a[t]←2*x+1,b[t]←3*x+1,t←t+1;
(3)将队列a和队列b的头结点进行比较,可能有三种情况:
(A)a[ha]>b[hb]
(B)a[ha]=b[hb]
(C)a[ha]
将比较的小者取出送入X,取出数的队列的头指针相应加1。
(4)重复(2),(3)直至取出第N项为止。
注意:数组的上标定到1000,当N较大时会出现队满溢出的情况,可以将上标定大些,或改用循环链表进行改进。
例3、求两个一元多项式的和。输入多项式方式为,多项式项数,每项系数和指数,按指数从大到小的顺序输入。
分析
多项式的算术运算是表处理的一个经典问题。建立两张表a、b分别存放两个多项式的内容,建立表指针ta、tb,指向表a和表b的元素,根据表a、b元素中的指数大小合并输出。
1、比较ta、tb指向元素的大小,若ta的指数大于tb的指数,输出ta元素,改变指针ta;
2、若ta的指数小于tb的指数,输出tb元素,改变指针tb;
3、若ta的指数等于tb的指数,ta、tb元素的系数相加输出,同时改变指针ta和tb;
4、若有一表取空,则输出另一表剩余的内容。
源程序一:多项式相加的顺序表实现
program ex11_5a;
type
node=record
zhi,xi:integer;
end;
ar=array[1..1000] of node;
var
a,b:ar;
ta,tb,n:integer;
begin
write('One : '); readln(n);{输入第一个多项式的系数