Ngôn ngữ lập trình Pascal - Phần 2
– Dữ liệu kiểu tập hợp là một tập hợp của những dữ liệu cùng thuộc một kiểu vô h-ớng đếm
đ-ợc (kiểu cơ sở của kiểu tập hợp).
– Một kiểu tập hợp đ-ợc định nghĩa bởi dạng sau:
TYPE
<tên kiểu> = SET OF<kiểu cơ sở> ;
trong đó <tên kiểu> là tên của kiểu dữ liệu cần định nghĩa <kiểu cơ sở> là tên hoặc là định nghĩa
một kiểu dữ liệu nào đó gọi là kiểu cơ sở.
dụng mảng thì bao giờ cũng cho số phần tử cực đại có thể dùng tới để khai báo
mảng và nếu ta dùng không hết thì gây ra lãng phí ô nhớ có thể đang thiếu cho việc khác. Nếu ta
dùng biến động thì cần đến đâu sẽ tạo ra đến đó. Hoặc nhiều khi ô nhớ bị hạn chế, nên ta không
104
thể đồng thời sử dụng nhiều biến tĩnh cùng một lúc. Do đó, một trong các biện pháp khắc phục là
dùng biến con trỏ để xây dựng một danh sách các phần tử móc nối với nhau gọi là danh
sách liên kết.
10.3.1. Định nghĩa
Danh sách liên kết là một danh sách mà các phần tử đ−ợc nối kết lại với nhau thông qua vùng
liên kết của chúng. Một phần tử của danh sách liên kết bao gồm hai vùng chính: Một vùng chứa
thông tin gọi là vùng Info, một vùng chứa địa chỉ gọi là vùng liên kết Link. Hình ảnh của một từ
máy (hay còn gọi là nut) nh− sau:
Info Link
Ngoài các phần tử thuộc danh sách liên kết, ta còn dùng một biến chỉ điểm đầu First (kiểu
Pointer) chứa địa chỉ của phần tử đầu tiên của danh sách liên kết. Tổ chức của danh sách liên kết
nh− sau
FIRST → |
↓
|
↓
|
↓
NIL
Ví dụ 5. Danh sách học viên có sắp xếp theo thứ tự tăng dần đ−ợc chứa trong một danh sách
liên kết nh− sau:
Vị trí Họ lót Tên Liên kết
0000
0032
0064
0096
0110
Mai Thị Ph−ơng
Nguyễn Châu
Lê Thị
Võ Thành
Hà Hải
Thảo
Ph−ơng
Lan
Lộc
Quân
NIL
0110
0096
0032
0000
1050064
FIRST
a. Loại bỏ một phần tử trong danh sách
Để loại bỏ một phần tử trong danh sách ta chỉ cần thay đổi vùng liên kết của phần tử đứng
ngay tr−ớc nó.
Ví dụ 6. Muốn loại bỏ tên học viên Võ Thành Lộc, ta chỉ cần sửa vùng liên kết của Lê Thị
Lan từ 0096 thành 0032 và các vùng liên kết của các phần tử còn lại vẫn giữ nguyên. Kết quả
ta có danh sách liên kết mới nh− sau :
Vị trí Họ lót Tên Liên kết
0000
0032
0064
0110
Mai Thị Ph−ơng
Nguyễn Châu
Lê Thị
Hà Hải
Thảo
Ph−ơng
Lan
Quân
NIL
0110
0032
0000
FIRST
0064
b. Thêm một phần tử mới vào danh sách
Để thêm một phần tử mới vào danh sách, ta có thể chứa phần tử này ở một vùng bất kì trong
bộ nhớ và cho vùng liên kết của phần tử đứng ngay sau nó.
Ví dụ 7. Muốn thêm tên học viên Trần Phúc Quyền vào danh sách, ta sửa vùng liên kết của
Hà Hải Quân từ 0000 thành 0200 và gán giá trị vùng liên kết của Trần Phúc Quyền là 0000.
Ta có danh sách liên kết nh− sau :
106
Vị trí Họ lót Tên Liên kết
0000
0032
0064
0096
0110
0200
Mai Thị Ph−ơng
Nguyên Châu
Lê Thị
Võ Thành
Hà Hải
Trần Phúc
Thảo
Ph−ơng
Lan
Lộc
Quân
Quyền
NIL
0110
0096
0032
0200
0000
FIRST
0064
Danh sách liên kết có −u điểm: Tốc độ thực hiện các phép toán thêm vào, loại bỏ phần tử
nhanh chóng, không phụ thuộc vào số phần tử của danh sách. Nó phù hợp với loại danh sách có
nhiều biến động. Nh−ợc điểm : Thêm vào một vùng biến liên kết (tốn thêm bộ nhớ).
10.3.2. Các phép toán trên danh sách liên kết
a. Khởi tạo danh sách liên kết
Khi khởi tạo danh sách thì danh sách là rỗng, ta cho First là NIL.
Giải thuật :
First:=NIL;
b. Thêm một phần tử vào danh sách liên kết
Phần tử mới có địa chỉ là P với nội dung là Newinfor và danh sách sau của phần tử là q.
Giải thuật :
New(P)
p^.info:=NewInfo;
p^.Link:=q^.Link; {Tao 1}
q^.Link:=p {Tao 2}
c. Loại bỏ phần tử trong danh sách liên kết
Loại bỏ phần tử có địa chỉ p ngay sau phần tử có địa chỉ q.
Giải thuật :
p:=q^.Link;
If pNIL Then
107
Begin
q^.Link:=p^Link;
Dispose(p)
End.
d. Tìm kiếm một phần tử trong danh sách
Giả sử danh sách đ−ợc sắp xếp thứ tự tăng dần theo vùng Info.
Ta tìm kiếm một phần tử có Info là X.
Giải thuật :
p:=First;
While p NIL Do
Begin
If p^.Info = X Then {...} ;
If p^.Info < X Then p=p^.Link ;
If p^.Info > X Then {...} ;
End;
10.3.3. Ví dụ về các danh sách liên kết
Ch−ơng trình sau đây thực hiện tổ chức danh sách sinh viên và thực hiện một số thao tác trên
danh sách. Độc giả có thể tìm thấy các phép xử lí trên danh sách thông qua các thủ tục trong
ch−ơng trình.
User Crt;
Type
svPointer=^sinhvien;
sinhvien = Record
Maso :String[6];
Hoten : String[30];
dtb : real;
Next : svPointer;
End;
108
Var
First, Last, p, q: svPointer;
Masv : String[6];
Chon1 : Byte ;
Traloi : Char;
Procedure Menu(Var cho : Byte);
Begin
Window(50,14,80,25):
Writeln (‘ ’);
Writeln (‘ Cac thao tac ’);
Writeln (‘ 1. Tao danh sach sinh vien ’);
Writeln (‘ 2. Duyet danh sach sinh vien ’);
Writeln (‘ 3. Bo sung vao cuoi danh sach ’);
Writeln (‘ 4. Loai bo ’);
Writeln (‘ 5. Cham dut ’);
Writeln (‘ **Chon so: ’);
GotoXY(21,8); Readln(Chon);
Clrscr;
End; { Menu }
(*------------------------------------------------------------------*)
Procedure Taosd;
Var
Ptr : svPointer;
i:Integer ;
Begin
First:=NIL;
i:=1 ;
Repeat
Write(i:3,‘>Mã số SV(Enter : Kết thúc):’);
109
Readln(masv);
If masv ‘ ’ Then
Begin
new(ptr);
Ptr^.maso:=masv;
Write(‘Ho va ten:’ );
Readln(Ptr^.Hoten);
Write(‘Diem trung binh:’);
Readln(Ptr^.dtb);
Ptr^.Next:=NIL;
If First =NIL Then First:=Ptr
Else Last^.Next:=Ptr;
Last:=Ptr;
i:=i+1;
End;
Until masv=‘ ’;
End; { Taods }
(*-----------------------------------------------------------*)
Procedure DuyetDS;
Var
Ptr :svPointer;
i: Integer;
Begin
Writeln(‘ DANH SACH SINH VIEN ’);
Writeln(‘ ==============================’);
Writeln(‘ STT Ma so Ho va ten DTB’);
Writeln(‘ ==============================’);
i:=1;
Ptr :=First;
While PtrNIL Do
110
Begin
Writeln(i:3,’ ‘,Ptr^.maso:5,’ ‘,Ptr^.hoten:25,’ ‘,Ptr^.dtb:5:2);
Ptr:=Ptr^.Next;
i:=i+1;
End;
End; { DuyetDS }
(*---------------------------------------------------------------*)
Procedure Themsv;
Var
Ptr:Pointer;
Begin
New(Ptr);
Writeln(‘Nhap thong tin mot sinh vien moi’);
Write(‘Mã số:’); Readln(Ptr^.maso);
Write(‘Họ tên:’); Readln(Ptr^.hoten);
Write(‘Điểm TB:’); Readln(Ptr^.dtb);
Ptr^.Next:=NIL; Last^.Next:=Ptr; Last :=Ptr;
End; { ThemSV }
(*--------------------------------------------------------------*)
Procedure XoaSV;
Var
Timco: Boolean;
Begin
Write(‘Ma so sinh vien can loai khoi danh sach:’);
Readln(masv);
p:=First;
If p NIL Then
Begin
Timco:=False;
While(pNIL) And Not Timco Do
111
If p^.maso=masv Then Timco:=True
Else
Begin
q:=p;
p:=p^.Next;
End;
If Timco Then
Begin
If p=First Then First:=p^.Next
Else q^.Next=p^.Next;
If p^.Next=NIL Then Last :=q;
Dispose(p);
End;
End;
End; { Xoa SV }
(*-----------------------------------------------------------*)
Begin
Clrscr;
Writeln(‘ VI DU DANH SACH LIEN KET ‘);
Writeln(‘ ==========================’);
Repeat
Menu(chon1);
Case chon1 Of
1: TaoDS;
2: DuyetDS
3: Begin
Repeat
Themsv ;
Write(‘Co tiep tuc khong (C/K) ?:’); Readln(Traloi);
Until Upcase(Traloi)=’K’;
112
End;
4: Begin
Repeat
XoaSV;
Write(‘Co tiep tuc nua khong (C/K)? :’); Readln(Traloi);
Until Upcase (Traloi)=‘K’;
End;
End; { Of Case }
Until chon1 = 5;
End.
Câu hỏi – Bài tập Ch−ơng 10
1. Sử dụng hàm Radomize (Hàm khởi tạo bộ nhớ ngẫu nhiên) và hàm Random (Hàm tạo một số
ngẫu nhiên trên đoạn [0,1]) để tạo một mảng ngẫu nhiên gồm 10000 phần tử.
2. Lập ch−ơng trình nhân hai ma trận A(m,n) và B(n,p) để đ−ợc ma trận tích C(m,p). Các mảng
A,B,C đều khai báo d−ới dạng biến con trỏ.
3. Viết ch−ơng trình tạo một danh sách liên kết chứa các số nguyên nhập vào từ bàn phím. Từ đó
viết thuật toán :
a) Đếm xem danh sách có bao nhiêu nút.
b) Tính giá trị trung bình của các phần tử trong danh sách.
c) Xác định nút cuối cùng của danh sách đó.
d) Xác định nút có giá trị lớn nhất của danh sách đó.
e) Xác định nút có giá trị âm đầu tiên của danh sách đó (nếu có).
f) Chèn một số nguyên X vào sau nút thứ n trong danh sách.
g) Xoá 1 phần tử n trong danh sách, n là số nguyên cho tr−ớc.
4. Viết ch−ơng trình nhập vào một dãy số thực có số phần tử tuỳ ý và sắp xếp dãy số đó theo thứ
tự tăng dần.
5. Viết ch−ơng trình nhập vào một dãy số thực đã đ−ợc sắp xếp theo thứ tự tăng dần (số phần tử
tuỳ ý) và một số thực X. Viết ch−ơng trình chèn số X vào danh sách sao cho dãy số mới cũng
có thứ tự tăng dần.
113
6. Viết ch−ơng trình nhập vào một danh sách các sinh viên (số sinh viên tuỳ ý), mỗi sinh viên có 2
tr−ờng : họ tên, tuổi. In ra danh sách đó theo thứ tự ng−ợc lại.
7. Hãy lập ch−ơng trình đọc vào hai dãy số và tổ chức chúng thành hai danh sách liên kết. Thực
hiện các phép xử lí sau đây trên hai danh sách :
a) Phần giao của 2 danh sách.
b) Phần hợp của 2 danh sách.
c) Hiệu của danh sách thứ nhất và danh sách thứ hai.
Ghi chú : không cần phải tạo danh sách mới trong mỗi thuật toán.
8. Viết ch−ơng trình cho phép nhập vào 2 dãy số tăng dần và l−u vào 2 danh sách liên kết, trộn 2
danh sách trên bằng cách tạo ra một danh sách mới sao cho dãy số hợp thành cũng tăng dần.
9. Viết ch−ơng trình tạo ra 2 danh sách liên kết (tuỳ ý) và nối 2 danh sách đó lại thành 1 danh
sách.
10. Viết ch−ơng trình nhập vào một dãy số và l−u trữ trong một danh sách liên kết sau đó xác
định xem các phần tử danh sách có giá trị tăng dần hay không.
11. Viết ch−ơng trình để biểu diễn một số nguyên lớn (Ví dụ : 1234567891234567) thành một
danh sách tuyến tính động.
12. Viết ch−ơng trình tính tổng của 2 số nguyên có độ lớn tuỳ ý.
13. Dùng cấu trúc dữ liệu để thực hiện tính n! mà không dùng đệ quy.
14. Một đa thức đã cho có thể đ−ợc biểu diễn d−ới dạng một danh sách tuyến tính động, trong đó
mỗi nút của danh sách gồm 2 tr−ờng :
* Tr−ờng chứa hệ số ai.
* Tr−ờng chứa số mũ i (ai 0, ∀i).
Hãy viết ch−ơng trình :
a) Nhập vào 2 đa thức.
b) Cộng 2 đa thức đó.
c) Tính f(x) với x là 1 số cho tr−ớc.
114
Chịu trách nhiệm nội dung:
Ts. Nguyễn văn hòa
Biên tập:
Tổ công nghệ thông tin
Phòng khảo thí - đảm bảo chất l−ợng giáo dục
Đơn vị phát hành:
trung tâm đào tạo từ xa - đại học huế
115
File đính kèm:
Ngôn ngữ lập trình Pascal - Phần 2.pdf

