Tải bản đầy đủ (.doc) (6 trang)

stack và queue

Bạn đang xem bản rút gọn của tài liệu. Xem và tải ngay bản đầy đủ của tài liệu tại đây (87.09 KB, 6 trang )

KIỂU DỮ LIỆU STACK VÀ QUEUE
Nguyễn Thế Anh
Ngoài các kiểu dữ liệu chuẩn như array, string,… mà PASCAL hỗ trợ thì còn có các kiểu dữ liệu trừu tượng
khác trong đó 2 kiểu dữ liệu STACK và QUEUE có ứng dụng rất rộng rãi. Hôm nay tôi xin giới thiệu với các
bạn chi tiết về 2 kiểu dữ liệu này.
I. Stack (Ngăn xếp).
Đây là kiểu dữ liệu mà việc cập nhật và truy nhập nó đều theo nguyên tắc ″Vào sau ra trước″(Last In, Firt Out
viết tắt là LIFO). Ta có thể hình dung Stack là một mảng, một chiều mà việc truy nhập và cập nhật nó đều diễn
ra ở một đầu của mảng. Sau đây là mô tả quy tắc hoạt động của Stack:
Ta dùng mảng Stack[I. Nmax] mà ″đáy″ của Stack là ở đầu tức chỉ số là 1. Việc đưa vào (Push) hay lấy ra (Pop)
được thực hiện phần đuôi của mảng nhờ một con trỏ P. Các thao tác đưa vào hay lấy ra đó ứng với các thủ tục
hàm thích hợp. Giả sử Stack chứa các phần tử là các số nguyên thì ta sẽ có các thủ tục và hàm sau:
Procedure Push (N:Integer); {Đưa số N vào Stack}
Begin
Inc (P);
Stack[P]:=N;
End;
Function Pop: Integer;
{Lấy 1 phần tử ra khởi stack}
Begin
Pop:=Stack[P];
Dec(P);
End;
Function StackEmpty:Boolean; {Kiểm tra stack có rỗng không}
Begin
StackEmpty:=P=0;
End;
Ví dụ:
Khử đệ quy thuật toán sắp xếp Quicksort;
Const
Nmax=5000;


Var
n, i, j, x, l, r, tg:Integer;
s: 0.. Nmax;
A: Array[1..Nmax] of Integer;
Stack: Array [1..Nmax] of Record l,
r : Integer;
End;
Procedure Sort;
Begin
S:=1; Stack [s].l:=1;
Stack [s].r:=n ;
Repeat
l:=Stack[s].1; r:=Stack[s].r;
Dec(s);
Repeat
i:=1; j:=r;
x:=A[(1+r)div 2]
Repeat
1
While a[i] < x
Do Inc(i);
While a [j] > x
Do Dec (j);
if i < = j then
Begin
Tg:=a[i]; a[i]:=a[j];
a[j]:=tg; Inc(i); Dec (j);
End;
Until i >j;
If i < r then

Begin
S: = s +1 ;
Stack [s].l: = 1;
Stack [s].r:= r ;
End; r : = j;
Until 1> r ;
Until S= 0;End;
II. Queue (Hàng đợi)
Khác với Stack, Queue là một kiểu dữ liệu trừu tượng mà cơ chế cập nhật và truy xuất xảy ra ở hai đầu khác
nhau và theo quy tắc vào trước ra trước (First In − First Out viết tắt là FIFO). Nếu có thể xác định được kích cỡ
cần đến của Queue ta có thể dùng một mảng tĩnh (thay cho một xâu liên kết động) để mô phỏng Queue theo đó,
đầu trái của mảng là đầu ra (dùng con trỏ l) và đầu phải của mảng là đầu vào (dùng con trỏ r) tương ứng với thủ
tục Put, hàm Get và một hàm Qfull kiểu Boolean để thông báo Queue đầy hay chưa.
Giả sử mảng mô phỏng Queue là Q:
Const
SizeQ = 5000;
Type
Td = Record d,c: Integer; End;
Var
Q: Array [1.. SizeQ ] of Td;
L,R: Integer;F: Text;
Procedure Put (NewOb:Td);
{Đưa vào hàng đợi }
Begin
Inc (R);
Q[r-1) div Sizequ +1]: = NewOb;
End;
Procedure Get(Var FistOb :Td); {lấy ra khỏi hàng đợi }
Begin
Inc(L);

FistOb:=Q[L Mod SizeQư1];
End;
Function Qempty:Boolean;
{Kiểm tra hàng đợi có rỗng hay không }
Begin
Qempty:=L – R >0;
End;
Function Qfull: Boolean; {Kiểm tra xem hàng đợi đã đầy hay chưa }
Begin
2
QFull : = r – 1 > SizeQ;
End;
ứng dụng quan trọng của Queue là giúp giải pháp ″Loang″ hay tìm kiếm theo chiều rộng.
Ví dụ: Trên bàn cờ vua quốc tế N*N ( n≤ 50) trong đó có một số ô có mìn. Từ một ô không có mìn cho trước
con mã có thể đi đến một ô khác được hay không. Nếu được hãy chỉ ra đường đi ngắn nhất.
File dữ liệu:
- Dòng 1 là N (kích thước bàn cờ).
- Dòng thứ nhất trong số N dòng tiếp theo:
* đầu tiên là K số mìn trên dòng đó, tiếp theo là K số, mỗi số là chỉ số cột có mìn.
- Dòng cuối ghi 4 số d1, c1,d2, c2:
* (d1,c1): toạ độ ô xuất phát.
* (d2,c2): Toạ độ ô đích.
Nhận xét: Với bài này ta có thể ứng dụng loang theo chiều rộng như sau:
Dùng một mảng A[i,j]:
+ A[i,j] = 0 nếu ô (i,j) có mìn.
+ A[i,j] = 1 nếu ô (i,j) không có mìn và mã chưa đến.
+ A[i,j]= k (k>1) nếu ô (i,j) là bước thứ k của con mã.
Put(ô xp); {đưa vào hàng đợi toạ độ ô xuất phát}.
Nhan { ô xp }: = 0; {khởi tạo nhãn của ô xuất phát}
Repeat

For { ô kề ô 1} do
if {ô để không có mình} then
if { ô kề chưa đến} then
Begin
Nhan [ôkề]: = Nhan [ô] +1;
Put (ô kề)
End;
Until QuEmpty;
if Nhan [ô đích] = vô cùng Then { thông báo không đến}
Else
Repeat
Tìm lật ngược kể từ ô đích;
Until Nhan [ô i] = 0;
Dưỡi đây là toàn bộ chương trình:
{$ R-, Q-}
Uses Crt;
Const
Dd:aray[1..8] of -2.. 2 = (-2,-2,-1.-1, 1, 1, 2, 2);
Cc:array[1..8]of -2.. 2 = (-1, 1, -2, 2, -1,1);
Sizequeue = 500;
Sodo = 1=1; {in so do duong di}
Fo =′ Ma. Out′;
Type
Size = 0.. 10;
Oco = Record d,c : Size; End;
Var
A:Array{Size, Size} of Word;
Q:Array{1.. Sizequeue}ofoco;
{queue}
d1, c1, d2, c2, n : Size;

3
Maxqueue,l,r : Longint;
Procedure Reađata;
Var Filename : String [50];
f : Text;
k, h : Size ;
Begin
Clrscr ;
Write (′Ten tep du lieu: ′);
Readln (Filename);
Assign(f,Filename); Reset(f);
Readln (f,n);
Fillchar (A, Size of (A) , 1);
For 1 : = 1 to n do
Begin
Read (f, k);
For r : =1 to k do Begin Read (f, h) ; A [1,h] : = 0; End;
Readln (f);
End;
Readln (f,d1,c1);
Close (f) ;
End;
Procedure Put (oo: oco);
Begin
Inc(r);
If r-1 > Maxqueue then
Maxqueue : = r -1;
Q{r-1) mod Sizequeue +1] : =oo;
End;
Procedure Get (Var oo: oco);

Begin
oo: =Q{ (1-1) mod Sizequeue+1];
Inc (1);
End;
Function Qempty: Boolean;
Begin
Qempty: =1>r ;
End;
Function Qfull: Boolean ;
Begin
Qfull : = r-1>Sizequeue;
End;
Function Thuchienduoc: Boolean;
{Kiểm tra xem có đường di hay không}
Var co,oo1: oco; i:Byte;d,c :Integer;
Begin
If A{d1,c1} = 0 then
Begin
Thuchienduoc : = False; Exit;
End;
Thuchienduoc: = True; 1: = 1;
4
r: = 0;
oo. d:= d1; oo.c: = c1;
A{d1, c1}:=2;
Put (oo);
Repeat
Get (co);
For i : = 1 to 8 do
Begin

d: = co.d + đ{1};
c : = oo. cc[i];
If (1≤d) and (d≤n) and (1≤c) and (c≤n) then
If A[ d, c] = 1 then
Begin
A {d, c};
i = A[oo.d,oo.c ]+1;
If (d=d2 )and (c=c2) then Exit;
If qfull then …………
Begin
Thuchienduoc : = False; Exit;
End;
oo1.d:= d;
oo1.c:= c ;
Put (oo1);
End;
End;
Until Qempty ;
Thuchienduoc : = False ;
End;
Procedure
Path {d,c : Size } ; { Tim duong di}
Var i , dx, cx : Integer ;
Begin
If A[d, c] > 2 then
Begin
For i:=8 Downto 1 do
Begin
dx : = d + đ [1] ;
cx := c+ cc[i];

If (1 ≤ dx) and (dx ≤n) and (1≤ cx) and (cx ≤n) then
If A {d,c} = A{x,cx}+1 then Break;
End;
Path (dx,cx);
End;
If sodo then
Begin
If A {d,c}>2 then Write (′——>′) ;
Write (′(′ , d, ′, ′, c,′) ′);
End ;
A{d,c}:=A {d,c} + n * n ;
End;
5

Tài liệu bạn tìm kiếm đã sẵn sàng tải về

Tải bản đầy đủ ngay
×