Danh sách móc nối đơn 2.. Danh sách móc nối vòng 3.. Danh sách móc nối kép 4.. Minh hoạ chèn mới b.
Trang 1I Lý thuyết
1 Danh sách móc nối đơn
2 Danh sách móc nối vòng
3 Danh sách móc nối kép
4 Stack và Queue
- Stack
- Queue
5 Bài tập áp dụng:
- Bài 14 (a, b, c)
- Bài 15 (c, d: bổ sung, loại bỏ theo Stack)
- Bài 17 (a, b)
II Bài tập
BÀI 11
a Minh hoạ chèn mới
b Chương trình:
type contro = ^nut;
nut = record info : real;
next : contro;
end;
var L,p: contro; {day so thuc}
i, n: integer; {so phan tu}
so,max : real;
begin
L := nil; {khoi tao dsach rong}
write('n = '); readln(n);
for i:=1 to n do begin
write('so = '); readln(so);
new(p); {cap phat bo nho}
p^.info := so; {luu info}
p^.next := L; {k.nap vao L}
L := p; {dieu chinh DS}
end;
{tim max}
p := L;
max := p^.info;
while p <> nil do {ds khac rong}
begin
if p^.info > max then max := p^.info;
p:= p^.next; {nut tiep theo}
end;
writeln('max = ',max:6:2);
readln;
end.
c Các lỗi thường gặp:
• Chưa khởi tạo danh sách rỗng L := nil;
• Chưa cấp phát bộ nhớ cho biến con trỏ new(p);
• Thiếu lệnh p:= p^.next; lặp vô hạn
L
HEAD
2 1
HEAD
SPUSH SPOP
QPOP QPUSH
2
L
(a) (b)
Trang 2BÀI 12
a Chương trình
program b12_daonguoc;
type stack_ctro = ^ nut;
nut = record
ch: char;
next : stack_ctro;
end;
mang = array[1 255] of char;
var sp: stack_ctro; {stack bang contro}
s: string;
n,i,top: integer;
sm : mang; {stack bang MANG}
procedure nguoc_ctro(s:string);
var p: stack_ctro;
begin
n:= length(s); {do dai xau}
{*} new(sp);
sp^.next := sp; {stack = rong}
for i:=1 to n do
begin {spush}
new (p);
p^.ch := s[i];
p^.next := sp^.next;
sp^.next := p;
end;
while sp^.next <> sp do {st<>rong}
begin {spop}
p := sp^.next;
write(p^.ch);
{**} sp^.next := p^.next;
dispose(p);
end;
end;
procedure nguoc_mang(s: string);
begin
top := 0; {stack = rong}
n := length(s);
for i:=1 to n do
begin {spush}
top := top + 1;
sm[top] := s[i];
end;
while top>0 do {stack <> rong}
begin {spop}
write(sm[top]);
top := top - 1;
end;
end;
begin
write('s = '); readln(s);
nguoc_ctro(s); writeln;
nguoc_mang(s);
end.
b Các lỗi thường gặp
{*} Chú ý cách khởi tạo danh sách nối vòng RỖNG {**} Chưa sp^.next := p^.next; mà đã dispose(p); Lỗi 204
BÀI 13
a Chương trình
program b13_xoaX;
type contro = ^nut;
nut = record info : real;
next : contro;
end;
var F,p,pm: contro;
n,i: integer;
so,X: real;
procedure tao_ds;
begin
F := nil; {khoi tao dsach rong}
write('n = '); readln(n);
for i:=1 to n do begin
write('so = '); readln(so);
new(p);
p^.info := so;
p^.next := F;
F := p; end;
end;
procedure xoa(x: real; var f: contro); var tr, p: contro;
begin {TH: Xoa dau dsach}
while (F<> nil) and (F^.info = x) do begin
tr:= F;
F := F^.next;
dispose(tr);
end;
{TH: Xoa giua, cuoi Dsach}
if F<> nil then begin
tr:= F;
p := F^.next;
{*} while p <> nil do begin
if p^.info = x then begin
tr^.next := p^.next;
dispose(p);
p := tr^.next;
end
Trang 3else
begin
tr := p;
p := p^.next;
end;
end; {end_while}
end; {end_if}
end;
procedure hien(F: contro);
var p: contro;
begin
{**} p:= F;
while p<> nil do
begin
write(p^.info:6:2,' ');
p := p^.next;
end;
end;
begin
mark(pm);
tao_ds;
hien(f);
writeln;
write('x= '); readln(x);
xoa(x,F);
hien(f);
readln;
release(pm);
end.
B Các lỗi thường gặp
{*} Chú ý cách duyệt danh sách để xoá
{**} Chú ý lệnh p:= F; trước khi duyệt không
bị thay đổi F.
BÀI 14
a Chương trình
program b14_stack;
type contro = ^nut;
nut = record
info : integer;
next : contro;
end;
var p,pm: contro;
i,n,x: integer;
procedure hien(F: contro);
var p: contro;
begin
p:= F;
while p<> nil do
begin
write(p^.info,' ');
p := p^.next;
end;
end;
procedure spush(var p: contro;
x: integer);
var tg : contro;
begin {*} new(tg);
tg^.info := x;
tg^.next := p;
p:= tg;
end;
function spop(var p:contro): integer; var x: integer;
tg: contro;
begin
if p<> nil then begin
x := p^.info;
tg := p;
p := p^.next;
dispose(tg);
{**} spop := x;
end else writeln('dsach rong!');
end;
procedure xoa_7(var F: contro);
var tr, p: contro;
begin while (F <> nil) and (F^.info mod 7 = 0) do begin
tr:= F;
F := F^.next;
dispose(tr);
end;
{TH: Xoa giua, cuoi Dsach}
if F<> nil then begin
tr:= F;
p := F^.next;
while p <> nil do begin
if p^.info mod 7 = 0 then begin
tr^.next := p^.next;
dispose(p);
p := tr^.next;
end else begin
tr := p;
p := p^.next;
end;
end; {end_while}
end; {end_inf}
end;
Trang 4procedure bosung(var p: contro;
x: integer);
var found : boolean;
it : contro;
begin
if p = nil then
begin
new(p);
p^.info := x;
p^.next := nil;
end
else
begin
found := false;
it := p;
while it^.next <> nil do
begin
if it^.info = x then
begin
found := true;
break;
end;
it := it^.next;
end; {end_while}
if (it^.info <> x) and
(found = false) then
begin
new (it^.next);
it^.next^.info := x;
it^.next^.next := nil;
end
else
writeln(x, ' da co ')
end; {end_if}
end;
begin
mark(pm);
write('n = '); readln(n);
for i:=1 to n do
begin
write ('x = '); readln(x);
spush(p,x);
end;
hien(p);
writeln('Top = ',spop(p));
hien(p);
xoa_7(p); hien(p);
write('nhap so moi : '); readln(x);
bosung(p,x); hien(p);
release(pm);
end.
b Các lối thường gặp
{*} Chưa cấp phát bộ nhớ cho nút mới
{**} Quên trả lại giá trị của hàm
Quên kiểm tra danh sách rỗng
BÀI 15
a Chương trình
program b15_sapxep;
type contro = ^nut;
nut = record info : word;
next : contro;
end;
var Head,p,pm : contro;
n,so,i: word;
procedure tao_ds(var head: contro); begin
new(head);
Head^.next := head;
head^.info := 0;
write('n = ');
readln(n);
randomize;
for i:=1 to n do begin
{*} so := random(999) + 1;
new(p);
p^.info := so;
p^.next := head^.next;
head^.next := p;
end;
end;
procedure hien(Head: contro);
begin
p := head^.next;
while p <> head do begin
write(p^.info:4);
p := p^.next;
end;
writeln;
end;
function min(head : contro) : contro; var pmin: contro;
begin
p := head^.next;
pmin := p;
while p <> head do begin
if pmin^.info > p^.info then pmin := p;
p := p^.next;
end;
{**}min := pmin;
end;
Trang 5procedure sapxep(var head: contro);
var r: contro;
tg: word;
begin
p := head^.next;
while p <> head do
begin
r := p^.next;
while r <> head do
begin
if p^.info > r^.info then
begin
{***} tg := p^.info;
p^.info := r^.info;
r^.info := tg;
end;
r := r^.next;
end; {end_r}
p := p^.next;
end; {end_p}
end;
procedure chen_xoa(var head: contro;
k: word );
var tg,r: contro;
xoa,chen : boolean;
begin
p := head;
r := head^.next;
xoa := false;
chen := false;
while r <> head do
begin
if r^.info = k then
begin
xoa := true;
break;
end
else
if r^.info > k then
begin
chen := true;
break;
end
else
begin
p := r;
r := r^.next;
end;
end; {end_while}
if xoa then
begin
p^.next := r^.next;
dispose(r);
writeln('DA XOA!');
end;
{****}if chen or (r = head) then
begin new(tg);
tg^.info := k;
tg^.next := r;
p^.next := tg;
writeln('DA CHEN');
end; {end_if}
end;
begin mark(pm);
tao_ds(head);
hien(head);
p := min(head);
writeln('min = ',p^.info);
sapxep(head);
hien(head);
write('so = '); readln(so);
chen_xoa(head,so);
hien(head);
release(pm);
readln;
end.
b Các lối thường gặp
{*} Chú ý có cộng thêm 1, nếu không cộng thì sẽ xuất hiện số 0 sai giả thiết.
{**} Trả lại giá trị cho hàm {***} Hoán đổi giá trị (INFO) chứ không hoán 2 con trỏ cho nhau
{****} r = head : không tìm thấy K phải chèn
vào Lúc này biến CHEN đang là False
BÀI 16
procedure xoa_giong(var head: contro); var r,tg: contro;
begin
p := head^.next;
while p <> head do begin
r := p;
while r^.next <> head do begin
if r^.next^.info = p^.info then begin
tg := r^.next;
r^.next := tg^.next;
end else
r := r^.next;
end;
p := p^.next;
end;
end;
Trang 6BÀI 17
a Chương trình
program b17_kep;
type contro = ^nut;
nut = record
info : word;
left : contro;
right: contro;
end;
var head,pm : contro;
procedure bosung(var head : contro;
x : word);
var p: contro;
begin
new (p);
p^.info := x;
p^.right := head^.right;
p^.left:= head;
head^.right^.left := p;
head^.right := p;
end;
function loaibo(var head:contro):word;
var p: contro;
x: word;
begin
if (head^.left = head) and
(head^.right = head) then
writeln('RONG!')
else
begin
p := head^.right;
x := p^.info;
p^.right^.left := head;
head^.right := p^.right;
dispose(p);
loaibo := x;
end;
end;
procedure tao_ds;
var i: word;
begin
new(head);
head^.left := head;
head^.right := head;
i := 20;
while i > 0 do
begin
bosung(head,i);
i := i-2;
end;
end;
procedure chen_xoa(var head : contro;
n : word); var chen,xoa: boolean; p, moi: contro; begin
chen := false;
xoa := false;
p := head^.right;
while p <> head do begin
if p^.info = n then begin
xoa := true;
break;
end else
if p^.info > n then begin
chen := true;
break;
end else p := p^.right;
end;
if chen then begin
new(moi);
moi^.info := n;
moi^.left := p^.left;
moi^.right := p;
p^.left^.right := moi;
p^.left := moi;
exit;
end;
if xoa then begin
p^.left^.right := p^.right;
p^.right^.left := p^.left;
dispose(p);
end;
end;
procedure hien;
var p: contro;
begin
p := head^.right;
while p <> head do begin
write(p^.info,' ');
p := p^.right;
end;
writeln;
end;
begin tao_ds;
chen_xoa(head,3); hien;
chen_xoa(head,20); hien;
end.