Cây nhị phân1... Đếm số nút lá ~ toán hạng function sonutlat:cay:integer; begin if t= nil then sonutla:=0 else... Cây nhị phân tìm kiếm 2.. Tìm kiếm nút chứa khóa k.. Loại bỏ một nút P
Trang 1I Cây nhị phân
1 0 Khai báo
type cay = ^nut;
nut = record
info: integer;
trai, phai: cay;
end;
var t: cay;
1 1 Dựng cây nhị phân
procedure chen(var t:cay;n:integer);
begin
if t = nil then
begin
new(t);
t^.info := n;
t^.trai := nil;
t^.phai := nil;
end
else
if n = t^.info then
writeln(n, ' da co')
else
if n > t^.info then
chen(t^.phai,n)
else chen(t^.trai,n);
end;
1 2 Các phép duyệt cây đệ quy
procedure truoc(t: cay);
begin
if t<> nil then
begin
write(t^.info:3);
truoc(t^.trai);
truoc(t^.phai);
end;
end;
(***********************)
procedure giua(t:cay);
begin
if t<> nil then
begin
giua(t^.trai);
write(t^.info:3);
giua(t^.phai);
end;
end;
(***********************)
procedure sau(t:cay);
begin
if t<> nil then begin
sau(t^.trai);
sau(t^.phai);
write(t^.info:3);
end;
end;
1 3 Duyệt cây không đệ quy type
mang1 = array[1 100] of cay; mang2 = array[1 100]of byte; var s: mang1;
r: mang2; {Stack để đánh dấu có được
{ phép thăm hay không}
ts,tr: integer;
(*****************) procedure spush(var s:mang1;p: cay); begin
ts := ts + 1;
s[ts] := p;
end;
(************) function spop(var s: mang1) : cay; begin
if ts>0 then begin
spop := s[ts];
ts := ts -1;
end;
end;
(******************************) procedure rpush(var r: mang2; n : byte);
begin
tr := tr + 1;
r[tr] := n;
end;
(************) function rpop(var r:mang2): byte; var n: byte;
begin
if tr>0 then begin
n := r[tr];
tr := tr - 1;
rpop := n;
end;
end;
procedure truoc(t: cay);
var p:cay;
Trang 2begin
ts := 0;
p := t;
if t<> nil then
spush(s,p);
while ts>0 do
begin
p:= spop(s);
write(p^.info:3);
if p^.phai <> nil then
spush(s,p^.phai);
if p^.trai <> nil then
spush(s,p^.trai);
end;
end;
procedure Giua(t: cay);
var p:cay;
begin
ts := 0;
p := t;
repeat
{Nộp p cùng nhánh lệch trái vào Stack}
while (p<> Nil) do
begin
spush(S, p);
p:= p^.Trai;
end;
p:= spop(S);{Lấy p ra từ Stack}
write(p^.info:3); {Thăm p}
p:= p^.Phai; {sang con phải của p}
until (ts = 0) and (p = Nil);
end;
procedure sau(t: cay);
var p:cay;
n: integer;
begin
ts := 0;
tr := 0; {khởi tạo 2 Stack rỗng}
p := t;
repeat
{Nộp p cùng nhánh lệch trái vào
Stack, nhưng sẽ chưa được phép thăm, R[tr] = 1}
while (p<> Nil) do
begin
SPUSH(S, p);
RPUSH(R, 1);
p:= p^.Trai;
end;
{lấy ra từ 2 Stack}
p:= SPOP(S);
n:= RPOP(R);
if (n = 1) and
(p^.Phai <> Nil) then
begin {sẽ được thăm sau, R[ts] = 2}
SPUSH(S, p);
RPUSH(R, 2);
P:= p^.Phai;
end else {(n=2) or (p^.Phai = nil) thăm} begin
write(p^.info:3); {thăm}
p:= Nil;
end;
until (TS = 0) and (p = Nil); end;
1 4 Tính chiều cao của cây function max(a,b: integer): integer; begin
if a>b then max := a else max := b;
end;
function chieucao(t:cay):integer; begin
if t=nil then chieucao := 0 else
chieucao := 1 + max(chieucao(t^.trai), chieucao(t^.phai)); end;
1 5 Đếm số đếm nút cành (~ toán tử) function sonutcanh(t:cay):integer; begin
if t= nil then sonutcanh:=0 else
if (t^.trai = nil) and (t^.phai = nil) then sonutcanh:=0
else sonutcanh:=1 + sonutcanh(t^.trai) + sonutcanh(t^.phai); end;
procedure lietkecanh(t:cay);
begin
if t = nil then write(' ') else
if (t^.trai <> nil) or (t^.phai <> nil) then begin
write(t^.info:3);
lietkecanh(t^.trai);
lietkecanh(t^.phai);
end;
end;
1 6 Đếm số nút lá (~ toán hạng ) function sonutla(t:cay):integer;
begin
if t= nil then sonutla:=0 else
Trang 3if (t^.trai=nil) and
(t^.phai=nil) then
sonutla:=1
else sonutla:= sonutla(t^.trai)+
sonutla(t^.phai);
end;
(***********************)
procedure lietkela(t:cay);
begin
if t = nil then write(' ')
else
if (t^.trai=nil) and
(t^.phai=nil) then
write(t^.info:3)
else
begin
lietkela(t^.trai);
lietkela(t^.phai);
end;
end;
II Cây nhị phân tìm kiếm
2 1 Tìm kiếm nút chứa khóa k.
Giải thuật đệ quy
function tim_dq(t:cay;k:Integer:cay;
begin
if (t=NIL) or (t^.info=k) then
tim_dq := t
else
if (T^.info < k) then
tim_dq:=tim_dq(T^.phai, k)
else
tim_dq:=tim_dq(T^.trai, k);
End;
Giải thuật lặp
Function Tim(T:cay;K:Integer):cay;
Var p: cay;
Begin
P:= T;
While (p<>Nil) and (p^.info<>k) do
If (p^.info < k) then
p:= p^.Phai
Else
P:= p^.Trai;
Tim:= p;
End;
2 2 Loại bỏ một nút P
Giả sử P đã có trong cây.
Giải thuật đệ quy
Procedure LoaiBo(Var t:cay; p: cay);
Begin
If p = T Then
Begin {XOÁ GỐC}
If (p^.Trai = Nil) Then t:= t^.Phai
Else Begin
r:= T^.Trai;
While r^.Phai <> Nil Do r:= r^.Phai;
R^.Phai:= T^.Phai;
T:= T^.Trai;
End;
Dispose(p);
End Else {P không trùng gốc}
If (p^.info < T^.info) Then LoaiBo(T^.Trai, p) Else LoaiBo(T^.Phai, p);
End;
Giải thuật lặp
Procedure LoaiBo2(Var t:cay;p: cay); Var q, r: cay;
Begin
q := t;
{TH: P trùng với GỐC xoá gốc }
If (p = T) Then begin
If (p^.Trai = Nil) Then T:= p^.Phai
Else Begin
r:= p^.Trai;
While (r^.Phai <> Nil) Do r:= r^.Phai;
r^.Phai:= T^.Phai;
T:= p^.Trai;
End;
exit; {Thoát chương trình con}
end;
{TH: P <> GỐC Tìm nút Q, mà:
Q^.Trai = P hoặc Q^.Phai = P}
While (q^.Trai <> p) and (q^.Phai <> p) Do begin
If (q^.info < p^.info) Then q:= q^.Phai
Else q:= q^.Trai;
end;
{Điều chỉnh lại các con trỏ trên cây}
If p^.Trai = Nil Then {Cụt trái} begin
If q^.Trai = p Then q^.Trai:= p^.Phai Else q^.Phai:= p^.Phai end
Trang 4Else {Cụt phải}
Begin
If (q^.Trai = p) Then
q^.Trai:= p^.Trai
Else q^.Phai:= p^.Trai;
R:= p^.Trai;
While (R^.Phai <> Nil) Do
R:= R^.Phai;
R^.Phai:= p^.Phai;
End; Dispose(p);
End;
2 3 Bổ sung một nút mới
Procedure Bosung(T:cay; K:Integer);
Var p,r : cay; OK: Boolean;
Begin {1}
If (T = NIL) Then
Begin
New(T);
T^.info := k;
T^.Trai:= NIL;
T^.Phai:= NIL;
End
Else
Begin {2}
P:= T; OK:= True;
While (p^.info <>k) and OK do
If (p^.info > k) Then
If (p^.Trai<>NIL) Then
p:= p^.Trai
Else OK:= False
Else
If (p^.Phai<>NIL) Then
p:= p^.Phai
Else OK:= False;
If (p^.info = k) Then
Write(k,' da ton tai')
Else
Begin {3}
New(r);
R^.info:= k;
R^.Phai:= NIL;
R^.Trai:= NIL;
If (p^.info > k) Then
p^.Trai := r
Else p^.Phai:= r;
End; {3}
End; {2}
End; {1}
2 4 Tìm nút cực đại (tận cùng phải)
function nutmax(t : cay):cay;
var p: cay;
begin
If t = nil then nutmax := nil
else
begin
p := t;
while p^.phai <> nil do
p := p^.phai;
nutmax:= p;
end;
end;
2 5 Tìm nút cực tiểu (tận cùng trái) function nutmin(t : cay):cay;
var p: cay;
begin
If t = nil then nutmin := nil else
begin
p := t;
while p^.trai <> nil do
p := p^.trai;
nutmin:= p;
end;
end;
2 6 Dựng cây nhị phân tìm kiếm
Cho danh sách tăng dần, dựng cây nhị phân tìm kiếm cho danh sách đó, sao cho chiều cao cây là nhỏ nhất.
procedure dung(var t:cay;
dau, cuoi: integer); var m: integer;
begin
if dau <= cuoi then begin
m := (dau + cuoi) div 2;
new(t);
t^.info := a[m]; {gốc của cây} dung(t^.trai, dau, m-1);
dung(t^.phai, m+1, cuoi);
end;
end;
5
9 1
Để hiểu các thuật toán thì cần phải
chương trình với
1 ví dụ cụ thể.