Ngăn xếp là một dạng đặc biệt của danh sách mà việc bổ sung hay loại bỏ một phần tử đều được thực hiện ở 1 đầu của danh sách.. Hàng đợi là một cấu trúc dữ liệu gần giống với ngăn xếp, nh
Trang 1ĐẠI HỌC PHÚ YÊN KHOA KỸ THUẬT – CÔNG NGHỆ
BÁO CÁO BÀI TIỂU LUẬN
ĐÊ TÀI: NGĂN XẾP,HÀNG ĐỢI TÍNH GIÁ TRỊ BIỂU THỨC THEO PHƯƠNG PHÁP NGHỊCH ĐẢO
BA LAN
GIÁO VIÊN HƯỚNG DẪN: TRẦN MINH CẢNH
SINH VIÊN THỰC HIỆN : NHÓM 2
LỚP : ĐẠI HỌC SƯ PHẠM TIN HỌC – C13 MÔN HỌC : CẤU TRÚC DỮ LIỆU VÀ THUẬT TOÁN
Trang 3LỜI MỞ ĐẦU
Cấu trúc dữ liệu và thuật toán là một trong những môn học cơ bản của sinh viên ngành Công nghệ thông tin Các cấu trúc dữ liệu và các giải thuật được xem như là 2 yếu tố quan trọng nhất trong lập trình, đúng như câu nói nỗi tiếng của Niklaus Wirth: Chương trình= Cấu trúc dữ liệu + Giải thuật (Programs=Data Structures+
Algorithms) Nắm vững các cấu trúc dữ liệu và các giải thuật là cơ sở
để sinh viên tiếp cận với việc thiết kế và xây dựng phần mềm cũng như sử dụng các công cụ lập trình hiện đại.
Hai cấu trúc dữ liệu rất gần gũi với các hoạt đọng trong thực tế,
đó là ngăn xếp và hàng đợi.
Ngăn xếp là một dạng đặc biệt của danh sách mà việc bổ sung hay loại bỏ một phần tử đều được thực hiện ở 1 đầu của danh sách Ngăn xếp còn được gọi là kiểu dữ liệu có nguyên tắc LIFO (Last In First Out- Vào sau ra trước).
Hàng đợi là một cấu trúc dữ liệu gần giống với ngăn xếp, nhưng phần tử được lấy ra khỏi hàng đợi không phải là phần tử mới nhất được đưa vào mà là phần tử đã được lưu trong hàng đợi lâu nhất Quy luật này được gọi là vào trước ra trước (FIFO- First In First Out).
Những gì đã đạt được:
-Tìm hiểu được cơ sở lý thuyết của ngăn xếp và hàng đợi.
- Biết được các ứng dụng của ngăn xếp
- Biết cách chuyển đổi biểu thức từ dạng trung tố sang hậu tố.
- Tính được biểu thức theo phương pháp nghịch đảo BaLan -Viết được chương trình ngăn xếp và tính biểu thức nghịch đảo BaLan.
Những gì chưa đạt được
- Chưa Demo được 2 chương trình đã viết
- Ứng dụng khử đệ quy của ngăn xếp chưa được tìm hiểu kĩ
Trang 4Mục lục
A.Ngăn xếp và hàng đợi………2
I.Ngăn xếp………2
1.Khái niệm……… 2
2.Tổ chức ngăn xếp bằng mảng 3
3.Các phép toán……… 4
a.Khởi tạo Stack……… 4
b.Các thao tác chính cho Stack……… 5
c.Chương trình Demo các thao tác trên Stack……7
4.Tổ chức ngăn xếp bằng danh sách liên kết……….8
5.Các ứng dụng của ngăn xếp……… 12
II.Hàng đợi(Queue) ……… 13
1.Khái niệm………13
2.Tổ chức hàng đợi bằng mảng……… 13
3 Các thao tác trên hàng đợi……….14
B Tính giá trị biểu thức theo phương pháp nghịch đảo Ba Lan ………16
I Thuật toán chuyển biểu thức dạng trung tố sang hậu tố 17
II Thuật toán tính giá trị biểu thức hậu tố ……… 19
III Chương trình Demo tính giá trị biểu thức nghịch đảo Ba Lan ……… 20
Trang 5Như vậy trong một ngăn xếp, phần tử vào sau sẽ lấy ra trước nên còn gọi là danh sách kiểu LIFO (Last in first out).Vị trí của phần tử của phần tử cuối cùng của ngăn xếp còn gọi là đỉnh(top)của ngăn xếp.
Các thao tác trên ngăn xếp gồm hai thao thao tác cơ bản là:
Push(x,S): Đưa phần tử x vào ngăn xếp
Pop(x,S): Lấy phần tử ở đỉnh ngăn xếp S ra và lưu vào biến x.Ngoài ra, còn có các thao tác bổ sung:
Trang 6 Init(S):Khởi tạo một ngăn xếp S rỗng.
Full(S): Cho biết ngăn xếp S có đầy không
Clear(S): Làm rỗng ngăn xếp S
Gettop(S): Lấy phần tử ở đỉnh ngăn xếp
Length(S): Cho biết số phần tử của ngăn xếp
2) Tổ chức ngăn xếp bằng mảng:
Một ngăn xếp tổ chức bằng mảng bao gồm hai thành phần:
Một mảng để lưu các phần tử của ngăn xếp
Trang 7Top : 0 MaxLength;
End;
Var S: StackArr
3.Các phép toán:
a.Khởi tạo stack:
Tạo 1 stack S rỗng : Top = 0
Giá trị của Top sẽ cho biết số phần tử hiện hành có trong stack:
Procedure Init(var S: StackArr);
Trang 8Empty := (S.top =0);
End;
b.Các thao tác chính cho Stack:
Thêm một phần tử x vào đỉnh ngăn xếp S:
Thêm phần tử A vào ngăn xếp Push (S,A)
A
Sau đó sẽ là phần tử B Push (S,B)
BA
Sau đó sẽ là phần tử C Push (S,C)
CBA
Procedure Push(x : ElementType; var S: StackArr);Begin
If not Full(S) then
Trang 9 Lấy phần tử cuối từ ngăn xếp S ra khỏi biến x:
Lệnh Pop(S) sẽ lấy phần tử mới được thêm vào ra khỏi Stack, đó là phần tử C
BA
Trang 10 Các thao tác trên đều làm việc với độ phức tạp 0(1)
Việc cài đặt Stack thông qua mảng một chiều đơn giản và khá hiệu quả
Tuy nhiên hạn chế lớn nhất của phương án cài đặt này là giới hạn về kích thước của Stack:
Là ta cần phải biết trước kích thước tối đa của ngăn xếp (giá trị max trong khai báo ở trên) Điều này không phải lúc nào cũng xác định được và nếu ta chọn một giá trị bất kỳ thì có thể dẫn đến lãng phí bộ nhớ nếu kích thước quá thừa so với yêu cầu hoặc nếu thiếu thì sẽ dẫn tới chương trình có thể không hoạt động
b Chương trình Demo các thao tác trên Stack
Trang 114 Tổ chức ngăn xếp bằng danh sách liên kết:
Để khắc phục nhược điểm của tổ chức ngăn xếp bằng mảng ta có thể sử dụng danh sách liên kết để cài đặt ngăn xếp
Để cài đặt ngăn xếp bằng danh sách liên kết, ta sử dụng 1 danh sách liên kết đơn Theo tính chất của danh sách liên kết đơn, việc bổ sung và loại bỏ một phần tử khỏi danh sách được thực hiện đơn giản và nhanh nhất khi phần tử đónằm ở đầu danh sách Do vậy, ta sẽ chọn cách lưu trữ của ngăn xếp theo thứ tự: phần tử đầu danh sách là đỉnh ngăn xếp, và phần tử cuối cùng của danh sách là đáy ngăn xếp
Hình ảnh của ngăn xếp S=(a1,a2,…,an) tổ chức bằng danh sách liên kết như sau:
a 1
Trang 12Để bổ sung 1 phần tử vào danh sách, ta tạo ra 1 nút mới và thêm nó vào đầu danh sách Để lấy 1 phần tử khỏi ngăn xếp, ta chỉ cần lấy giá trị nút đầu tiên
và loại nút ra khỏi danh sách
Đỉnh ngăn xếp Đáy ngăn xếp
Các thao tác trong tổ chức ngăn xếp bằng danh sách liên kết
Khởi tạo đỉnh ngăn xếp:
NIL
a 2
a n
Trang 13Thao tác này thực hiện việc gán giá trị null cho nút đầu ngăn xếp, cho biết ngăn xếp đang ở trạng thái rỗng.
Hàm Empty : Kiểm tra xem Stack có rỗng không
Funtion Empty (S: StackLink): Boolean;
Trang 15End;
End;
Làm rỗng ngăn xếp: xóa và thu hồi các ô nhớ
Procedure Clear(var S: StackLink);
Tổ chức ngăn xếp bằng danh sách liên kết thích hợp lưu trữ các loại dữ liệu
mà trình tự xuất ngược với trình tự lưu trữ
II)Hàng đợi: (Queue)
Trang 16+Lấy phần tử đầu ra khỏi hàng đợi.
Hàng đợi được thực hiện theo nguyên tắc : các phần tử đưa vào trước lấy
ra trước nên còn gọi là danh sách FIFO (Firt in Firt out)
Hàng đợi Q= ( a1;a2;…;an) được thể hiện bằng hình dưới
Lấy ra thêm vào
2.Tổ chức hàng đợi bằng mảng:
Hàng đợi tổ chức bằng mảng cũng giống như hình danh sách nhưng cần hai
thành phần để lưu vị trí phần tử sẽ được lấy ra ở đầu hàng đợi (front) và vị trí
phần tử thêm vào cuối cùng của hàng đợi (rear)
Trang 17Queue = Record
Elemen:Array[1 Maxlength] of ElementType;
Front , Rear:0 Maxlength;
Var Q:Queue;
3.Các thao tác trên hàng đợi:
Khởi tạo hàng đợi:
Procedure InitQueue(var Q:Queue);
Thêm phần tử x vào hàng đợi Q
Procedure themQueue(x:ElementType;var Q:Queue);
Begin
If not Full(Q) then
Begin
Q.rear := Q.rear +1;
Trang 18Q.element[Q.rear] : = x;
End;
End;
Lấy một phần tử ra khỏi hàng đợi Q:
Procedure RemoveQueue(var x:ElementType;var Q:Queue);
Begin
Ì not Emply(Q) then
Begin
X:=Q.elemeny[Q.front];
If Q.front = Q.rear then
Begin Q.front ;==1;Q rear := );end
B Tính giá trị biểu thức theo phương pháp nghịch đảo BaLan
Khi thực hiện chương trình, các ngôn ngữ lập trình thường phải tính giá
trị của biểu thức Thông thường, các ngôn ngữ lập trình tính giá trị biểu thức
bằng cách :
+ Chuyển biểu thức từ dạng trung tố(infix) sang dạng hậu tố (posfix)
Trang 19+ Tính giá trị biểu thức hậu tố.
Biểu thức trung tố là cách con người thường sử dụng, trong biểu thức
trung tố các phép toán hai ngôi được viết giữa hai toán hạng Việc tính trực
tiếp các biểu thức trung tố gặp khó khăn vì phải dùng các cặp dấu ngoặc đơn
để quy định thứ tự thực hiện các biểu thức con Để tính các biểu thức, người
BaLan đã đưa ra một ký pháp quy định cách viết các biểu thức( gọi là kí pháp
BaLan) trong đó các phép toán được đặt sau toán hạng Việc dùng kí pháp
BaLan không cần dấu ngoặc nhưng vẫn thể hiện được thứ tự ưu tiên khi tính
giá trị biểu thức nên dễ dàng xây dựng thuật toán tính
Ví dụ : Biểu thức dạng trung tố : 3+(5-2)*3/7-4
Chuyển sang dạng hậu tố là : 3 5 2 -3* 7/4 - +
Thuật toán chuyển biểu thức dạng trung tố sang dạng hậu tố :
Giả sử ta có một biểu thức E dạng trung tố trong đó ta có thể phân tích thành
các thành phần của biểu thức là các toán hạng và phép toán
Dùng một ngăn xếp S mỗi phần tử là phép toán hoặc dấu ngoặc mở Kết quả
đưa ra biểu thức hậu tố E1
I.Thuật toán chuyển biểu thức dạng trung tố sang hậu tố.
1 Khởi tạo biểu thức E1, rỗng
2 Duyệt lần lượt từ trái sang phải các thành phần cảu biểu thức E1, với
mỗi thành phần x thực hiện :
2.1 Nếu x là toán hạng thì nối vào bên phải biểu thức E1
2.2 Nếu x là dấu ngoặc mở thì đưa vào ngăn xếp
2.3 Nếu x là phép toán thì :
Trang 20a Đọc phần tử y ở đầu ngăn xếp.
b Nếu độ ưu tiên của y cao hơn hoặc bằng x thì
- Lấy y ra khỏi ngăn xếp
- Nối y vào bên phải E1
- Lặp lại bước a
c Nếu độ ưu tiên của x cao hơn y thì đưa x vào ngăn xếp
d Nếu ngăn xếp rỗng thì đưa x vào ngăn xếp
2.4 Nếu x là dấu ngoặc đóng thì :
a Đọc phần tử y ở đầu ngăn xếp
b Nếu y là phép toán thì :
- Lấy y ra khỏi ngăn xếp
- Nối y vào bên phải biểu thức E1
- (2Lặp lại bước a
c Nếu y là dấu ngoặc mở thì lấy ra khỏi ngăn xếp
3 Lặp lại bước 2 cho đến hết biểu thức E
4 Lấy lần lượt các phần tử của ngăn xếp và nối vào bên phải biểu thức E1
cho đến khi ngăn xếp rỗng
Ví dụ : Với biểu thức E=(2+7*3-8)*4-(3+2)*3-2, thuật toán chuyển thành
biểu thức hậu tố thực hiện các bước được thể hiện qua các kết quả ở bảng
Trang 22Cho biểu thức viết dưới dạng hậu tố E1 Để tính giá trị của biểu thức ta dùng
một ngăn xếp S lưu các toán hạng và các kết quả tính toán trung gian
Thuật toán
1 Duyệt lần lượt cac phần tử của biểu thức E1, với thành phần x thực
hiện :
a Nếu x là toán hạng thì đưa vào ngăn xếp
b. Nếu x là phép toán thì lấy hai phần tử đầu ngăn thực hiện tính theo phép toán và đưa kết quả vào ngăn xếp
2 Lặp lại bước 1 cho đến khi hết biểu thức
3 Giá trị duy nhất còn lại của ngăn xếp là kết quả của biểu thức E1
Ví dụ : Kết quả tính biểu thức hậu tố E1= 2 7 3*+8-4*3 2+3*-2- qua các bước được biểu diễn bởi bảng sau :
Trang 24for i := Length(S) - 1 downto 1 do {Xoá những dấu cách thừa}
if (S[i] = ' ') and (S[i + 1] = ' ') then Delete(S, i + 1, 1);
Trang 25Process(T); {Xử lý phần tử vừa đọc xong}
T := ''; {Đặt lại T để chuẩn bị đọc phần tử mới}