1. Trang chủ
  2. » Giáo án - Bài giảng

de va dap an de thi cao hoc mon ct du lieu

34 25 0

Đang tải... (xem toàn văn)

Tài liệu hạn chế xem trước, để xem đầy đủ mời bạn chọn Tải xuống

THÔNG TIN TÀI LIỆU

Nội dung

Nhằm xây dựng cây nhị phân tìm kiếm có gốc được trỏ bởi Goc; tương ứng với một hoán vị nào đó của các phần tử trong danh sách sao cho độ cao của cây nhận được là nhỏ nhất. Giải:[r]

(1)

DANH SÁCH MÓC NỐI

Biến động (Nút) Cấu trúc nhị phân:

Đối với có ba phép duyệt: - Gốc – Trái – Phải

- Trái – Gốc – Phải - Trái – Phải – Gốc Ví dụ:

A BDE CFGH Cây nhị phân tìm kiếm:

Là nhị phân chứa dãy khóa thỏa mãn điều kiện khóa gốc lớn khóa nút trái nhỏ khóa nút phải

Ví dụ:

Nhận xét:

Duyệt theo phương án: Trái – Gốc – Phải : 11 15 16 17 19 25 cho dãy khóa theo thứ tự tăng dần Như việc tìm kiếm nút chứa khóa k Nếu tìm có cho địa nút đó, khơng cho địa NULL

Function Timnut(T: Tro; K: Integer): Tro; Var p: Tro;

Begin

P:= T;

While (p<> Nil) and (p^.Giatri <> k) If (p^.Giatri < k then p:= p^.Phai Else

P:= p^.Trai; Timnut:= p;

End;

Tìm theo đệ quy:

Function Timnut(T: Tro; k: Integer):Tro; Begin

If (T=NIL) or (T^.Giatri= k) Then Timnut:= T

Else

If (T^.Giatri > k) Then

Timnut: = Timnut(T^.Phai, k)

x

A

E

C

B

F

D

G

H

Trái Phải

15

11

25

9

17

5

(2)

Else

Timnut:= Timnut(T^.Trai, k); End;

2.1 Bổ sung thêm khóa K vào T (nếu chưa có nút chứa K): Procedure Bosung(T: Tro; K: Integer);

Var p,r : Tro; OK: Boolean; Begin

If (T=NIL) Then Begin

New(T);

T^.Giatri: = k; T^.Trai:= NIL;

T^.Phai:= NIL; End Else Begin

P:= T; OK:= True;

While (p^.Giatri <> k) and OK If (p^.Giatri > 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^.Giatri = k) Then Write(“Gia tri da ton tai”)

Else Begin

New(r); R^.Giatri:= k;

R^.Phai:= NIL; R^.Trai:= NIL;

If (p^.Giatri > k) Then p^.Trai := r Else p^.Phai:= r; End;

End; End;

Đề thi năm 2003:

Câu 2: Người ta biểu diễn thông tin câu lạc bóng đá chuyên nghiệp quốc gia dạng nhị phân tìm kiếm có khóa TenCLB (Tên câu lạc bộ) Mỗi nút ghi gồm trường: TenCLB trường trỏ Left, Right, First Hai trỏ Left Right lần lượt trỏ tới nút trái phải nút Con trỏ First trỏ phần tử đầu danh sách liên kết đơn chứa thông tin cầu thủ thuộc câu lạc (danh sách có 11 phần tử) Mỗi phần tử danh sách ghi gồm trường: TenCT (Tên cầu thủ), SoAo (số áo), Tuoi (tuổi), Next (lưu địa phần tử danh sách) Danh sách theo thứ tự tăng dần SoAo Người ta cho khai báo cấu trúc liệu nói sau:

Type st25 = string[25]; TroCT = ^Cauthu; Cauthu = Record

TenCT: St25; SoAo, Tuoi: Byte; Next: TroCT; End;

TroCLB = ^Nut; Nut = Record

TenCLB: St25; First: TroCT; L,R: TroCLB; End;

Var Top: TroCLB;

TenCLB

First

R

L

TenCLB

R

L

TenCT

L

TenCLB

R

SoAo

Tuoi

Next

(3)

a Viết thủ tục in danh sách cầu thủ câu lạc có tên club Procedure List(Club: st25);

Var P: TroCLB; r: TroCT; Begin

P:= Top;

While (p<> Nil) and (p^.TenCLB <> Club)

If (p^.TenCLB > Club) Then p:= p^.L else p:= p^.R; If p= Nil Then Write(“Khơng có câu lạc này”)

Else Begin

r:= p^.First;

Writeln(“Danh sách cầu thủ”); While r<> Nil

Begin

Writeln(p^.TenCT); r:= r^.next;

End; End; End;

2 Viết thủ tục Procedure Bosung(Top: TroCLB; Name: st25; m,k: byte) bổ sung cầu thủ tên Name, tuổi k, số áo m vào câu lạc có tên Club> Việc bổ sung thực trường hợp câu lạc Club có chưa có cầu thủ câu lạc có số áo

Procedure Bosung(Top: TroCLB; Name: st25; m,k: byte); Var p: TroCLB; q, r: TroCT;

Begin

p:= Top;

While (p<> Nil) and (p^.TenCLB <> Club)

If (p^.TenCLB > Club) Then p:= p^.L Else p:= p^.R; If (p = Nil) Then Write (“Khơng có Câu lạc này”)

Else

Begin

R:= p^.First;

{Con trỏ r dùng để duyệt nút cho r dừng lại nút thỏa mãn điều kiện sau:

Số áo m

Số áo < m số áo nút > m Hoặc nút cuối

}

If (r^.SoAo > m) or (p^.First = Nil) then Begin

New(q); q^.TenCT = Name;

q^.Tuoi:= k; q^.SoAo:= m;

q^.Next: = p^.First; p^.First:= q;

End Else Begin

While (r^.Next <> Nil) and ((r^.Next)^.SoAo <= m ) r:= r^.Next;

If r^.SoAo = m then Write (“Đã có”) Else

Begin

New(q);

q^.TenCT:= Name; q^.Tuoi:= k; q^.SoAo:= m; q^.Next:= r^.Next; r^.Next:= q; End;

(4)(5)

c Xóa tên cầu thủ mang số áo m câu lạc Club Procedure Xoa(Club: st25; m: byte);

Begin p:= Top;

While (p<> Nil) and (p^.TenCLB <> Club)

If (p^.TenCLB > Club) Then p:= p^.L Else p:= p^.R; If (p = Nil) Then Write (“Khơng có Câu lạc này”)

Else

Begin

R:= p^.First;

While (r<> Nil) and (r^.SoAo <> m) r:= r^.Next; If (r=Nil) Then Write(“Khơng có nút chứa số áo này!”)

Else

Begin

If (r=p^.First) Then p^.First:= r^.Next Else

Begin

q:= p^.First;

While (q^.Next <> r) q:= q^.Next; q^.Next:= r^.Next;

End; Dispose(r); End;

End; End;

d Viết hàm Function TuoiMin(Club: st25): byte cho biết tuổi cầu thủ trẻ câu lạc có tên Club {Tìm giá trị nút}

Function TuoiMin(Club: st25): byte; Var k: byte;

Begin p:= Top;

While (p<> Nil) and (p^.TenCLB <> Club)

If (p^.TenCLB > Club) Then p:= p^.L Else p:= p^.R; If (p = Nil) Then Write (“Khơng có Câu lạc này”)

Else

Begin

r:= p^.First;

If (r=Nil) Then Write (“Câu lạc khơng có cầu thủ nào!”) Else

Begin

k:= r^.Tuoi; r:= r^.Next;

While (r<> Nil) Begin

If (r^.Tuoi < k) Then k:= r^.Tuoi; R:= r^.Next;

End; TuoiMin:= k; End;

End; End;

- Nếu tình tìm tên s cầu thủ có tuổi < I { Phải tìm nút có điều kiện }

- Nếu Câu lạc chưa có => phải bổ sung thêm câu lạc cầu thủ nút câu lạc

Bài 1: (Đề 2003) Type Link= ^Node; Node = Record

Key: Integer; Next: Link; End;

Var i, M,N: integer; t, x: Link; Begin

(6)

New(t); t^.key:= 1; x:= t; For i:= to N

Begin New(t^.Next); T:= t^.Next; T^.Key:= i; End; t^.Next:= x;

While (t<> t^.Next) Do Begin

For i:= to M-1 Do t:= t^.Next; Write(t^.Next^.Key);

x:= x^.Next;

t^.Next:= t^.Next^.Next; Dispose(x);

End; Writeln(t^.Key); End

a Cho biết kết với N=5; M= 3;

Kết quả: 3, 1, 5, 2,

b Chương trình thực cơng việc gì?

 Đầu tiên tạo danh sách nối vòng gồm n nút, chứa dãy số 1,2,3,…,n  Và có nút trỏ x, nút cuối trỏ t

 Nếu chừng t <> t^.next đồng nghĩa với danh sách có nút (từ nút trở lên)

nó thực hiện:

- Chuyển t sang quản lí nút sau t M-1 vị trí - Sau viết giá trị key nút sau t - Loại bỏ nút sau t

 Cuối viết giá trị nút trỏ t hình

Bài 3: (Đề thi 1996A)

Trong hệ soạn thảo văn soạn lưu nhớ dạng danh sách nối kép sau:

1

1

1

1

1

(7)

Khai báo danh sách (Đầu, Cuối) sau: Type str80 = string[80];

Tro = ^DongVB; DongVB = Record

Truoc: Tro; Dong: Str80; Sau: Tro; End;

Var Dau, Cuoi: Tro; {Dau = Nil văn rỗng} a Viết thủ tục dạng

Procedure Xemtruoc(Var d: Tro; p: Tro; S: str80);

Cho phép xen dòng với nội dung cho s vào trước phần trỏ p danh sách có đầu d

Giải:

// Trong thủ tục cần thêm c cuối danh sách để thủ tục hoàn chỉnh Procedure Xemtruoc(Var c,d: Tro; p: Tro; s: str80); Var r: Tro;

Begin

New®; r^.dong:= s;

r^.Truoc:= Nil; r^.Sau:= Nil; If (d= Nil) Then

Begin d:= r; c:= r;

End Else

If (p = d) Then Begin

r^.Sau:= p; p^.Truoc:= r; d:= r;

End Else

Begin

r^.Truoc:= p^.Truoc; r^.Sau:= p;

p^.Truoc^.Sau:= r; p^.Truoc:= r; End;

End;

c Gọi Blốc(db,cb) khối liền dòng kể từ dòng trỏ db đến dòng cb Hãy viết thủ tục chuyển dời Blốc(dc,cb) tới trước dòng trỏ Noiden danh sách (d,c) Giả sử nơi đến không Blốc

Giải:

Procedure ChuyenBL(Var d,c: Tro; db, cb, Noiden: Tro);

// Nơi đến có trường hợp: đến đầu văn văn

// Khi xây dựng thủ tục cần ý đến trường hợp đặc biệt sau: Trong Blốc có chứa dịng // trỏ đầu thay đổi

// Trong Blốc có chứa dòng cuối => trỏ cuối thay đổi

// Trong Blốc khơng chứa dịng dòng cuối Noiden: dòng địa //chỉ đầu thay đổi

// Nơi đến: khơng phải dịng địa đầu không thay đổi Var

Begin

If (db= d) then Begin

dd:= d; // Con trỏ dd quản lí đầu block, block dịng đầu văn d:= cb^.Sau; //trở thành dòng

cb^.sau:= Nil; d^.Truoc:= Nil;

(8)

cb^.Sau:= Noiden; Noiden^.Truoc:= cb; End

Else

Begin

db^.Truoc^.Sau:= cb^.Sau; cb^.Sau^.Truoc:= db^.Truoc; db^.Truoc:= Nil;

cb^.Sau:= Nil; End;

/* Ba trường hợp nằm chung nhiệm vụ cắt Block khỏi danh sách chứa văn Nhiệm vụ sau chèn Block vào trước dòng nơi đến */

Noiden^.Truoc^.Sau:= db; Db^.Truoc:= Noiden^.Truoc; Cb^.Sau:= Noiden;

Noiden^.Truoc:= cb;

c Viết thủ tục cho phép chép (mà không hủy) Block tới trước dòng trỏ Noiden danh sách đầu trỏ d Giả sử Noiden không Block

Giải:

Procedure ChepBL(Var d: Tro; db, cb, Noiden: Tro); /* Đối với thủ tục ta cần giải công việc sau:

+ Tạo danh sách độc lập ds,cs quản lí nút đầu cuối danh sách để chép nội dung Block:

- Chèn ds, cs vào trước dòng trỏ nơi đến */ Var

Begin

ds:= Nil; // Danh sách rỗng cs:= Nil;

// Trường hợp dừng p=Nil p^.Truoc = cb While (p <> Nil) and (p^.Truoc <> cb)

Begin

New(r); r^.dong:= p^.dong; r^.Truoc:= Nil;

r^.sau:= Nil; If (ds = Nil) Then

Begin

ds:= r; cs:= r;

End

Else begin

r^.Truoc:= cs; cs^.Truoc:= r; cs:= r;

End;

p:= p^.Sau; End;

// Chèn danh sách ds, cs vào trước nơi đến If (Noiden = d) then

Begin

cs^.Sau:= d; d^.Truoc:= cs; d:= ds;

End

Else Begin

Noiden^.Truoc^.Sau:= ds; //Noiden dịng văn

Ds^.Truoc:= Noiden^.Truoc; Cs^.Sau:= Noiden;

Noiden^.Truoc:= cs;

ds

(9)

End; End;

Đề 1997:

Bài 3: Kết thi đại học lớp lưu lại danh sách tuyến tính móc nối nút khai báo sau:

Type Tro = ^Nut; Nut = Record

Sohieu: integer; Tin: Alpha;

Toan, Ly, Hoa: Real; Tiep: Tro;

End;

Đầu danh sách trỏ biến Dau Var dau: Tro;

Hãy viết chương trình

1 Procedure Nhap(Var Dau: Tro; sh: Integer; Name: Alpha; t,l, h: real) cho phép nhập số hiệu sh, tên học sinh name điểm tốn, lý, hóa cho t, l, h tương ứng với nút đặt cuối danh sách lớp cho trỏ dau

Giải:

Procedure Nhap(Var Dau: Tro; sh: Integer; Name: Alpha; t,l, h: real) Var hs: Tro;

Begin

//Bổ sung nút vào cuối danh sách New(hs);

Hs^.sohieu:= sh; Hs^.ten:= Name; Hs^.Toan:= t; Hs^.Ly:= l; Hs^.Hoa:= h; Hs^.Tiep:= Nil;

If dau = Nil then Dau:= hs Else

Begin P:= Dau;

While p^.Tiep <> Nil Do p:= p^.Tiep; P^.Tiep:= Hs;

End; End;

2 Procedure Ketqua(Dchuan: real; Dau: Tro; Var Do, Truot: Tro);

Cho phép thơng báo danh sách học sinh đỗ (có trường điểm Tốn, Lý, Hóa lớn điểm chuẩn Dchuan) Danh sách trỏ trỏ Do danh sách học sinh bị trượt trỏ trỏ Truot

Yêu cầu: Không chép lại phần tử danh sách lớp học sang vùng nhớ danh sách cho

Giải:

Ý tưởng:

+ Dùng biến trỏ p để duyệt danh sách trỏ Dau + Tại vị trí p ta làm:

- Cắt p khỏi danh sách Dau

- Xem nút p đỗ hay trượt Nếu đậu bổ sung vào sau danh sách Đỗ (trỏ trỏ Do) Nếu trượt bổ sung vào danh sách trượt (trỏ trỏ Truot)

(10)

Procedure Ketqua(Dchuan: real; Dau: Tro; Var Do, Truot: Tro); Var p, r1,r2: Tro;

Begin

Do:= Nil; Truot: Nil; {2 danh sách rỗng chưa có nút nào} While (Dau <> Nil) Do

Begin

// Cắt p khỏi danh sách

P:= Dau;

Dau:= Dau^.Tiep; P^.Tiep:= Nil;

If (p^.Toan+ p^.Ly+p^.Hoa >= Dchuan) then //Nếu thi đậu

Begin

If (Do = Nil) Then Do:= p Else

r1^.Tiep:= p; r1:= p;

End Else

Begin

If (Truot = Nil) Then Truot:= p Else

r2^.Tiep:= p; r2:= p; End;

End; End;

Đề 1995 – B

Bài 1: Cho khai báo kiểu danh sách tuyến tính móc nối Type Tro = ^KieuPT;

KieuPT = Record

Giatri: Integer; Tiep: Tro;

End;

1.

Cho Var ds, q: Tro; ds rtỏ tới đầu danh sách tuyến tính Hãy viết thư mục Procedure LayMax(Var ds, q: Tro)

cho phép lấy phần tử lớn khỏi danh sách ds, phần tử trỏ q Giải:

Procedure LayMax(Var ds, q: Tro) Var r: Tro;

Begin

q:= ds; r:= q^.Tiep; While (r <> Nil) Do

Begin

If (r^.Giatri > q^.Giatri) Then q:= r; r:= r^.Tiep;

End;

If (q = ds) then ds:= ds^.Tiep Else

Begin

r:= ds;

While r^.Tiep <> q r:= r^.Tiep; r^.Tiep:= q^.Tiep;

End; q^.Tiep:= Nil; End;

2

1

7

3

r = Nil

r

ds

(11)

2 Cho Var ds1, ds2: Tro;

Trong ds1, ds2 trỏ đầu danh sách tuyến tính chưa xếp theo trường Giatri cịn ds2 gán Nil Viết thủ tục:

Procedure Sapchon(Var ds1, ds2: Tro);

Cho phép chọn dần phần tử ds1 từ giá trị lớn đến bé, đưa vào ds2 để cuối ds1 = Nil ds2 trỏ tới danh sách tuyến tính gồm phần tử ds1, xếp theo thứ tự tăng dần trường Giatri

Giải:

Procedure Sapchon(Var ds1, ds2: Tro); Var

Begin

While (ds1 <> Nil) Do Begin

LayMax(ds1, q);

If ds2 = Nil Then ds2:= q

Else //Bổ sung q vào đầu danh sách d2 để theo thứ tự tăng dần

Begin

LayMax(ds, q); q^.Tiep:= ds2; ds2:= q;

End; End;

End; Đề 1997:

Bài 3: Cây nhị phân kiểu Min – Max có tổ chức sau:

- Mỗi nút chứa trường giá trị khóa, có kiểu liệu Integer; Type Nut = Record

Giatri : Integer; Kieu: Boolean; Trai, Phai: ^Nut; End;

TroNut = ^Nut; Quy ước:

Kiểu = T nút thuộc loại MAX

F nút thuộc loại MIN

a Viết thủ tục đệ quy để tính giá trị nút nhị phân trỏ trỏ gốc, dựa khóa nút

Function TinhGiaTri (Goc: TroNut): Integer; Function Min(a,b: Integer): Integer;

Function Max(a,b: Integer): Integer; Begin

If (Goc^.Trai = Nil) and (Goc^.Phai = Nil) Then TinhGiaTri:= Goc^.Giatri;

Else

If (Goc^.Kieu = T) Then //Nút có kiểu MAX

10

7

6

10

12

6

10

(12)

TinhGiaTri:= Max(TinhGiaTri(Goc^.Trai), TinhGiaTri(Goc^.Phai))

Else

TinhGiaTri:= Min(TinhGiaTri(Goc^.Trai), TinhGiaTri(Goc^.Phai))

End;

Procedure TaoCayB(Goc: TroNut); Begin

If (Goc^.Trai = Nil) and (Goc^.Phai <> Nil) then Begin

Goc^.Giatri:= TinhGiaTri(Goc); TaoCayB(Goc^.Trai);

TaoCayB(Goc^.Phai); End;

End;

b Viết thủ tục tính giá trị trung bình giá trị Khóa nút Procedure TimTong(Var S, SoNut: Integer; Goc: TroNut); Begin

S:= S+ Goc^.Giatri; SoNut:= SoNut + 1;

If (Goc^.Trai <> Nil) and (Goc^.Phai <> Nil) Then Begin

TimTong(s, SoNut, Goc^.Trai); TimTong(s, SoNut, Goc^.Phai); End;

End;

Procedure TrungBinh(Goc: TroNut); Var S, SoNut: Integer; p: TroNut; Begin

S:= 0; SoNut:= 0; p:= Goc; TimTong(S, SoNut, p);

Write(“Trung bình là: “, S/SoNut); End;

Xây dựng phương án không đệ quy cho câu 1: + Duyệt theo thứ tự sau (Trái phải gốc)

+ Mỗi lần thăm nút: Tùy theo nút MIN hay MAX mà chọn giá trị cho nó, lấy trái phải(Nếu nút thăm nút lá)

Nhắc lại duyệt không đệ quy nhị phân: Duyệt trước: (Gốc – trái - Phải)

- Nộp Goc vào Stack - REPEAT

o Lấy nút p từ Stack o Thăm p

o Nếu có phải nạp vào Stack o Nếu p có trái nạp vào Stack UNTIL Stack rỗng

A

C

B

E

D

F

G

K

H

I

(13)

A B D E K C F H I G

Duyệt giữa: (Trái - Gốc - Phải) + p:= Goc;

+ REPEAT

- Nộp p nhánh lệch trái vào Stack - Lấy p từ Stack

- Thăm p

- Chuyển p sang gốc phải p (có thể Nil) UNTIL (Stack rỗng) and (P = NIL)

Procedure DuyetGiua(Goc: TroNut) Var

Begin

//Khởi tạo Stack S = 0;

p:= Goc; Repeat

While (p<> Nil) Begin

Push(S, p); p:= p^.Trai; End;

p:= Pop(S);

Write(p^.GiaTri,” “); p:= p^.Phai;

Until (S =0) and (p = Nil); Return ;

End;

Duyệt sau: (Trái - Phải - Gốc) Procedure TaoCay(Goc: TroNut);

Type MangTro = Array[1 100] of Integer; Var S: MangTro; R: Mang;

N, TS, TR: Integer; P: TroNut;

Procedure SPUSH(S: MangTro; Var TS: Integer; P: TroNut); Begin

TS:= TS + 1; S[TS] := p; End;

Function SPOP(S: MangTro; Var TS: Integer): TroNut; Begin

TS:= TS -1 ; SPOP:= S[TS+1]; End;

Procedure RPUSH(R: Mang; Var TR: Integer; n: Integer); Begin

TR:= TR + 1; R[TR]:= n; End;

Function RPOP(S: Mang; Var TS: Integer): Integer; Begin

TR= TR-1 ;

RPOP:= R[TR + 1];

G I H

(14)

End; BEGIN

TS:= 0; TR:= 0; p:= Goc; Repeat

While (p<> Nil) Begin

SPUSH(S, TS, p); RPUSH(R, TR, 1); p:= p^.Trai; End;

p:= SPOP(S, TS); n:= RPOP(R,TR);

If (n=1) and (p^.Phai <> Nil) then Begin

SPUSH(S, TS, p); RPUSH(R,TR,2); P:= p^.Phai; End;

Else

//Thăm nút tính giá trị Min, Max Begin

If (p^.Trai <> Nil) and (p^.Phai <> Nil) Then If (p^.Kieu = T) Then

p^.GiaTri:= Max(p^.Trai^.GiaTri, p^.Phai^.GiaTri)

Else

p^.GiaTri:= Min(p^.Trai^.GiaTri, p^.Phai^.GiaTri);

p:= Nil; End;

Until (TS =0) and (p = Nil); END;

Đề 1993:

Cho nhị phân với khai báo sau: Type Tro = ^Nut;

Nut = Record

Giatri: Integer; Trai, Phai: Tro; End;

Var T: Tro;

Hãy lập hàm Function Copy(T: Tro): Tro; cho phép chép với gốc trỏ T Function Copy(T: Tro): Tro;

Begin

If (T = Nil) Then Begin

New(p);

P^.GiaTri:= T^.GiaTri; P^.Trai:= Copy(T^.Trai); P^.Phai:= Copy(T^.Phai); Copy:= p;

End; End;

Bài 4:

Với nhị phân khai báo 3, ta tiến hành duyệt theo giải thuật không đệ quy theo sơ đồ sau, có danh sách tuyến tính để lưu (các trỏ tới) nút cần ghi nhớ

(15)

Begin

- Lấy nút từ danh sách, gọi N - Thăm N (chẳng hạn in giá trị

- Nạp trỏ trái N vào danh sách (nếu có) - Nạp trỏ phải N vào danh sách (nếu có) End;

Giải thuật S (Dùng Stack) (lấy nút (nạp muộn nhất)) Giải thuật Q (dùng Queue) lấy nút cũ (nạp sớm nhất) a Hãy cho biết giải thuật S, Q duyệt theo thứ tự nào? Giải:

Giải thuật S:

Stack: Kết quả: Giải thuật Queue: Queue: Kết quả:

Duyệt ưu tiên theo mức, mức ưu tiên từ trái sang phải

b Từ gợi ý sơ đồ trên, viết thủ tục duyệt nhị phân theo thứ tự (gốc- trái – phải) Chú ý không phá hoại cho cố gắng loại động tác thừa Thăm nút thể in giá trị nút

Giải:

Gốc – Trái – Phải:

S: ->

Procedure PreOrder(Goc: Tro); Var p: Tro; TS: Integer;

Procedure PUSH(S: MangTro; Var TS: Integer; p: Tro); Function POP(S: MangTro; Var TS: Integer): Tro; Begin

TS:= 0; //Khởi tạo danh sách rỗng PUSH(S, TS, Goc);

While (TS >0) Begin

p:= POP(S, TS); Write(p^.Giatri);

If p^.Phai <> Nil Then PUSH(S, TS, p^.Phai); If p^.Trai <> Nil Then PUSH(S, TS, p^.Trai); End;

End;

ĐỀ IFI 09/96 Bài 3:

Người ta biểu diễn thông tin thư viện dạng nhị phân tìm kiếm với khóa TenTG (tên tác giả) Mỗi nút ghi gồm trường TenTG trường trỏ: trỏ Trai Phai trỏ tới nút trái phải Hai trỏ Dau va Cuoi trỏ tới phần tử đầu cuối danh sách tuyến tính móc nối dùng để ghi nhận sách có thư viện tác giả Mỗi phần tử danh sách ghi gồm có trường: Tensach Tieptheo Có thể hình dung:

1

3

2

5

4

6

7

8

9

(16)

Người ta khai báo: Type Str25 = string[25];

Trosach = ^Record

Tensach: String; Tieptheo: TroSach; End;

TroTG = ^Tacgia; Tacgia = Record

Trai: TroTG; TenTG: str25; Dau, Cuoi: TroSach; Phai: TroTG; End;

Var Goc: TroTG;

a Hãy viết hàm Function Nut(Goc: TroTG; Ten: str25): TroTG; cho kết trỏ: - Bằng NIL Goc = Nil khơng thì:

- Trỏ tới nút có TenTG = Ten nút tồn tại, khơng thì:

- Trỏ tới nút Ten < TenTG Trai = Nil Trỏ tới nút Ten > TenTG Phai = Nil

Cây bên trái < bên phải tên xếp theo thứ tự Giải:

Function Nut(Goc: TroTG; Ten: str25): TroTG; Var p: TroTG;

Begin

If (Goc = Nil) Then Nut:= Nil Else

Begin

p:= Goc;

While ((Ten< p^.Tentg)and(p^.Trai <> Nil))or((Ten>p^.TenTG)and(p^.Phai<> Nil))

If (Ten < p^.TenTG) Then p:= p^.Trai Else p:= p^.Phai;

Nut:= p; End;

End;

b Hãy viết hàm cho ta địa (con trỏ kiểu TroTG) nút thành lập, chưa gắn vào cây, TenTG = Ten phần tử danh sách tương ứng TenSach = Tuade

Function NutMoi(Ten: str25; Tuade: string): TroTG; Var p: TroTG; r: TroSach;

Begin

New(p);

p^.TenTG:= Ten; p^.Trai:= Nil; p^.Phai:= Nil; New(r);

r^.TenSach:= Tuade; r^.Tieptheo:= Nil;

p^.Dau:= r; p^.Cuoi:= r; End;

c Hãy viết thủ tục cho phép bổ sung tên tác giả (Ten) với sách (Tuade) vào thư viện trỏ Goc theo cách sau:

- Nếu Ten TuaDe có thư viện khơng phải làm

Đầu

Trái Cuối Phải

x x

p

Trái

(17)

- Nếu Ten có Tuade chưa có bổ sung Tuade vào cuối danh sách tương ứng với nút có tên TenTG = Ten

- Nếu Ten TuaDe chưa có bổ sung nút vào thư viện, với TenTG = Ten TenSach = TuaDe

Giải:

Procedure Bosung(Var Goc: TroTG; Ten: str25; TuaDe: String); Var p: TroTG; r: TroSach;

Begin

p:= Nut(Goc, Ten);

If (p= Nil) Then Goc:= NutMoi(Ten, TuaDe) Else

If ((Ten < p^.TenTG) Then p^.Trai:= NutMoi(Ten, TuaDe) Else

If (Tem > p^.TenTG) Then p^.Phai:= NutMoi(Ten, TuaDe) Else

Begin

r:= p^.Dau;

While (r<> Nil) and (r^.TenSach<> TuaDe) Do r:= r^.TiepTheo;

If (r=Nil) Then Begin

New(r);

r^.TenSach:= TuaDe; r^.TiepTheo:= Nil;

If (p^.Dau = Nil) Then p^.Dau:= r Else

p^.Cuoi^.TiepTheo:= r; p^.Cuoi:= r;

End; End;

End; Đề 02/1998

Bài 2: Khai báo kiểu danh sách tuyến tính móc nối nhị phân sau: Type Tro = ^Ptu;

Ptu = Record

GiaTri: Integer; Tiep: Tro; End;

Pointer = ^Nut; Nut = Record

Value: Integer; Trai, Phai: Pointer; End;

Var ds: Tro;

Goc: Pointer;

Viết chương trình thực công việc sau:

1 Procedure Dungcay(ds:Tro; Var Goc: Pointer) nhằm xây dựng nhị phân tìm kiếm có gốc trỏ gốc sở phần tử danh sách ds cho Giả thiết phần tử danh sách có giá trị khác đơi

Ví dụ:

8 10

Ta xây dựng nhị phân tìm kiếm sau:

8

3

9

(18)

Giải:

Procedure Dungcay(ds: Tro; Var Goc: Pointer); Var

Procedure BosungNut(Var Goc: Pointer; n: Integer); Var r, p: Pointer;

Begin

New(r);

r^.Value:= n;

r^.Trai:= nil; r^.Phai:= Nil; If (Goc = nil) Then Goc:= r Else

Begin

p:= Goc;

While ((p^.Value < n)and(p^.Phai <>Nil)) OR ((p^.Value > n) and (p^.Trai <> Nil)) Do

If p^.Value < n Then p:= p^.Phai Else p:= p^.Trai If (p^.Value < n) Then p^.Phai:= r Else p^.Trai:= r; End;

End; BEGIN

q:= ds;

While (q <> Nil) Do Begin

BosungNut(Goc, q^.Giatri); q:= q^.Tiep;

End; END:

2 Nhằm xây dựng nhị phân tìm kiếm có gốc trỏ Goc; tương ứng với hoán vị phần tử danh sách cho độ cao nhận nhỏ

Giải:

Procedure Cay_NP_Min(Ds: Tro; Var Goc: Pointer); /*

+ Đầu tiên xếp dãy theo thứ tự tăng dần

+ Xóa đệ quy: Lấy giá trị đưa vào gốc sau gọi đệ quy dựng trái với dãy phía trước dựng phải với dãy phía sau:

*/ Type

Mang = Array[1 1000] ò Integer; Var A: Mang; n: Integer;

Procedure DocRaMang(Var A: Mang; Var n: Integer; Ds: Tro); /*

Đọc dãy số từ danh sách lưu vào mảng A Số phần tử dãy lưu vào n Sau xếp thứ tự tăng dần mảng A

*/

Procedure Dung(A: Mang; Dau, Cuoi: Integer; Var Goc: Pointer); Var Giua: Integer;

Begin

New(Goc);

Giua:= (Dau+Cuoi) Div 2; Goc^.Giatri:= A[Giua]; Goc^.Trai:= Nil;

1 10

T1

T1

Cuối

(19)

Goc^.Phai:= Nil;

If (Dau< Giua) Then Dung(A, Dau, Giua-1, Goc^.Trai); If (Giua <Cuoi) Then Dung(A, Giua + 1, Cuoi, Goc^.Phai); End;

BEGIN

DocRaMang(A, n, DS); Dung(A, 1, n, Goc); END; Bài 3: (Đề 1999-2000)

Cho khai báo nhị phân sau: Type Tro = ^Nut;

Nut = Record

GiaTri: Integer; Trai, Phai: Tro; End;

Var Goc: Tro;

Hãy lập chương trình thực cơng việc sau:

1 Hàm cho phép Kiểm tra xem có gốc trỏ trỏ gốc có phải nhị phân tìm kiếm hay khơng?

Chú ý: Cây rỗng coi tìm kiếm Viết theo phương án đệ quy không đệ quy Giải:

Đệ quy:

Function CayTK(Goc: Tro):Boolean; Begin

If ((Goc = Nil) Or ((Goc^.Trai = Nil) and (Goc^.Phai = Nil))) Then CayTK:= True

Else

Begin

If (Goc^.Trai = Nil) Then

If (Goc^.Giatri <Goc^.Phai^.Giatri) Then CayTK:= True

Else CayTK:= False Else

If (Goc^.Phai = Nil) Then

If (Goc^.Giatri > Goc^.Trai^.Giatri) Then CayTK:= True

Else CayTK:= False Else

CayTK:= CayTK(Goc^.Trai) and CayTK(Goc^.Phai) and

(Goc^.Giatri > Max(Goc^.Trai) and

(Goc^.Giatri < Min(Goc^.Phai) End;

End;

Function Max(Goc: Tro): Integer; Function Min(Goc: Tro): Integer;

Với giá trị trả hàm nút lớn nhỏ

2 Trường hợp ban đầu khơng phải tìm kiếm, viết thủ tục cho phép tráo đổi nội dung nút cây, không thay đổi cấu trúc cây, để nhận nhị phân tìm kiếm Giải:

Đọc vào mảng phải đọc theo thứ tự

8

7

6

4

3

1

9

4

8

3

6

1

9

7

3

1

(20)

Procedure SapLai(Goc: Tro);

Type Mang = Array[1 100] of Integer; Var n: Integer;

Procedure DocVaoMang(Goc: Tro; Var A: Mang; Var n: Integer); // n phần tử đưa vào có số thứ tự n mang thông tin

Begin

If Goc <> Nil) Then Begin

DocVaoMang(Goc^.Trai, A, n); n:= n + 1;

A[n]:= Goc^.GiaTri;

DocVaoMang(Goc^.Phai, A, n); End;

End;

Procedure XepThuTuTrenMang(Var A: Mang; n: Integer); Procedure DuaVaoCay(Goc: Tro; A: Mang);

Var i: Integer; Begin

If (Goc <> Nil) Then Begin

DuaVaoCay(Goc^.Trai, A, i); Goc^.GiaTri:= A[i];

i:= i + 1;

DuaVaoCay(Goc^.Phai, A, i); End;

End; BEGIN

N:= 0;

DocVaoMang(Goc, A, n); XepThuTuTrenMang(A, n); N:= 1;

DuaVaoCay(Goc, A, n); END;

TỔNG KẾT:

* Đối với nhị phân nói chung có phương án duyệt đệ quy không đệ quy - Gốc Trái Phải

- Trái Gốc Phải - Trái Phải Gốc

Thăm gốc: Có nghĩa ta quản lí địa nút hay gốc ta làm việc với nút tùy toán cụ thể

Cây nhị phân tìm kiếm: - Có giải thuật bản:

+ Tìm kiếm nút thỏa mãn điều kiện (dù nút gì) cho nút có, khơng cho địa Nil

+ Tìm nút có giá trị Khóa cho trước, có cho địa nút đó, cịn khơng bổ sung vào nút cuối cho địa nút

+ Loại bỏ nút:

10

7

15

4

(21)

 p khơng có trái  p có trái

Procedure LoaiBo(Var Goc: Tro; p: Tro); Begin

If (p=Goc) Then Begin

If (p^.Trai = Nil) Then Goc:= Goc^.Phai Else

Begin

r:= Goc^.Trai;

While r^.Phai <> Nil Do r:= r^.Phai R^.Phai:= Goc^.Phai;

Goc:= Goc^.Trai; End;

Dispose(p); End

Else // Khi gốc không trùng p

If (p^.GiaTri < Goc^.GiaTri) Then LoaiBo(Goc^.Trai, p) Else LoaiBo(Goc^.Phai, p);

End;

- Phải xác định trỏ quản lí p (trong nút đó) đóng vai trị quản lí gốc - Khi Goc = p: Có trái -> Loại bỏ gốc

Nếu khơng có -> Loại bỏ Khơng đệ quy:

+ Tìm nút q mà trỏ phải trái quản lí p: Procedure LoaiBo(Var Goc: Tro; p: Tro); Var q, r: Tro;

Begin

// Tìm nút q nhận p làm nút q:= Goc;

While (q^.Trai <> p) and (q^.Phai <> p) Do

If (q^.GiaTri <p^.GiaTri) Then q:= q^.Phai Else q:= q^.Trai; //Điều chỉnh lại trỏ

If (p^.Trai = Nil) Then

If q^.Trai = p Then q^.Trai:= p^.Phai Else q^.Phai:= p^.Phai Else

Begin

If (q^.Trai = p) Then q^.Trai:= p^.Trai Else q^.Phai:= p^.Trai;

//Nếu trỏ trái q = p -> Con trỏ trái q quản lí trỏ trái p ngược lại trỏ phải q quản lí trỏ trái p

r:= p^.Trai;

While (r^.Phai <> Nil) Do r:= r^.Phai; r^.Phai:= p^.Phai;

End; Dispose(p); End;

* Bổ sung thêm trường hợp p = Goc (p gốc) If (p= Goc) Then

If (p^.Trai = Nil) Then Goc:= p^.Phai Else

Begin

r:= p^.Trai;

While (r^.Phai <> Nil) Do r:= r^.Phai; r^.Phai:= Goc^.Phai;

Goc:= p^.Trai; End;

(22)

ĐỀ IFI 1997: Bài 4:

Người ta biểu diễn biểu thức số học với toán tử +, -, *, / hai +, - Trong với tốn tử chứa nút biến chứa Chẳng hạn: (((a+b)*c)-(((-c)/d/e)) biểu diễn sau:

Viết khai báo nhị phân nói Giả sử với biến có giá trị cho trước Hãy viết chương trình cho phép từ thành lập nhớ trên, tính giá trị biểu thức toán học liên quan

Giải: Type

Str25 = String[25]; Tro = ^Nut; Nut = Record

Giatri: Str25; Trai, Phai: Tro End;

Function Value(S: Str25): Integer; Var k, n: Integer;

Begin

Val(S, n, k); //Đổi chuỗi S thành số n, thành công k =0, có lỗi k<>

Value:= n; End;

Function GTBT(Goc: Tro): Real; Begin

If (Goc^.Trai = Nil) and (Goc^.Phai =Nil) Then GTBT:= Value(Goc^.GiaTri)

Else

Case Goc^.GiaTri Of

“*”:

GTBT:= GTBT(Goc^.Trai) * GTBT(Goc^.Phai);

“/” :

GTBT:= GTBT(Goc^.Trai) / GTBT(Goc^.Phai);

“+”:

If (Goc^.Trai = Nil) Then GTBT:= GTBT(Goc^.Phai) Else

GTBT:= GTBT(Goc^.Trai) + GTBT(Goc^.Phai);

“-“ :

If (Goc^.Trai = Nil) Then

GTBT:= - GTBT(Goc^.Phai) Else

-*

/

+

c

e

a

b

/

-

d

(23)

GTBT:= GTBT(Goc^.Trai) - GTBT(Goc^.Phai);

End; End;

2 Giả sử biểu thức số học với ngoặc đơn đầy đủ đọc sẵn vào biến lưu kiểu String Hãy viết chương trình thành lập biểu diễn biểu thức Cây lưu nhớ máy tính

Giải: Ý tưởng:

- Xác định toán tử với biểu thức nằm trước sau toán tử

- Tạo với gốc chứa tốn tử này, sau gọi đệ quy để tạo phải chứa biểu thức phía sau Nếu có biểu thức phía trước tạo trái chứa biểu thức

- Ngược lại tốn tử ngơi trái rỗng

Tình suy biến đệ quy: Khi xâu St khơng có dấu ngoặc (chỉ chứa biến) Procedure DungCay(Var Goc: Tro; St: String);

Var Begin

If (KiemTra(St)) Then

/* KiemTra(St) = T St khơng có dấu ngoặc

F St có chứa dấu ngoặc */ Begin

New(Goc);

Goc^.GiaTri:= St;

Goc^.Trai:= Nil; Goc^.Phai:= Nil; End

Else

Begin

If ((St[2] = “+”) or (St[2]= “-“)) Then Begin

New(Goc);

Goc^.GiaTri:= St[2];

Goc^.Trai:= Nil; //Vì biểu thức

Delete(St, 1, 2);

Delete(S, Length(St),1); DungCay(Goc^.Phai, St); End;

Else

Begin

n:= VitriToanTu(St); S1:= XauPhiaTruoc(St, n); S2:= XauPhiaSau(St, n); New(Goc);

Goc^.GiaTri:= St[n]; DungCay(Goc^.Trai, S1); DungCay(Goc^.Phai, S2); End;

End; End;

Function ViTriToanTu(St: String): Integer;

// Đếm vị trí tốn tử mà tốn tử tách biểu thức cho thành biểu thức trước //sau // Xác định xâu S1: For i:= to n -1

// Xác định xâu S2: For j:= n +1 to (length(S) -1) Do ĐỀ SỐ 2/1996

Bài 1:

Dãy Morse vô hạn xác định sau:

m = x0, x1, …, xn - Ban đầu: Viết phần tử x0 =

(24)

n = n-1 , n-1 dãy n-1 xây dựng từ dãy n-1 cách thay thành 1, thay thành

0 = 0; 1 = ,1 2 = 0, 1, 1,

1 Viết hàm đệ quy xây dựng giá trị phần tử thứ k dãy Morse Ví dụ; k = 0: x0 = 0;

k = 7; x7 = 1; …

Giải:

Suy biến đệ quy: k = 0; Nếu k >

0 = x5 phủ định x1 = 1; = x1 phủ định x0 = 0;

Function Phudinh(a: Integer): Integer; Begin

If (a = 0) Then PhuDinh:= Else

Begin

S:= 1;

// Số lượng phần tử k chạy từ Ví dụ k =6 -> có phần tử

While S < k+1 Do Begin

S:= S*2; M:= S div 2; End;

Xacdinh:= PhuDinh(Xacdinh(k-m)); End;

End;

2 Đưa phương án không dùng đệ quy: Giải:

Function Xacdinh(k: Integer): Integer; Var kk, i, Dem, a, m, S: Integer; Begin

kk:= k; Dem:= 0; While (kk > 0) Do

Begin

S:= 1;

While S < kk + Do S:= S*2; M:= S div 2;

Kk:= kk – m; Dem:= Dem + 1; End;

A:= 0;

For i:= to Dem Do a:= PhuDinh(a); Xacdinh:= a;

End;

Nếu không sử dụng (1) ta phải bỏ (3) (2) thay a:= Phudinh(a), thêm phép gán a:= 0; từ đầu

ĐỀ NĂM 1998 Bài 2:

Khai báo kiểu danh sách tuyến tính móc nối sau: Type Tro=^Nut;

Nut = Record

(25)

End; Var ds: Tro;

Viết chương trình thực công việc sau:

1 Function Doixung(ds: Tro): Boolean; nhằm kiểm tra xem danh sách ds có phải đối xứng hay không? Viết hai phương án lặp đệ quy

Đệ quy:

- Suy biến đệ quy: Danh sách rỗng -> Đối xứng

Danh sách có nút -> Đối xứng Function Doixung(ds: Tro): Boolean;

Var Begin

//Xét suy biến đệ quy

If (ds = Nil) or (ds^.Tiep = Nil) Then Doixung:= True Else

Begin

d:= ds; r:= ds; c:= r^.Tiep;

While c^.Tiep <> Nil Do Begin

r:= c;

c:= c^.Tiep; End;

If (d^.GiaTri <> c^.GiaTri) Then DoiXung:= False Else

Begin

r^.Tiep:= Nil;

Doixung:= Doixung(ds^.Tiep); End;

End; End;

Phương án lặp:

Function Doixung(Ds: Tro): Boolean; Var d, c, r: Tro; OK: Boolean; Begin

OK:= True; d:= Ds;

While ((d <> Nil) and (d^.Tiep <> Nil) and OK ) Do Begin

r:= d; c:= r^.Tiep;

While (c^.Tiep <> Nil) Do Begin

R:= c;

C:= c^.Tiep; End;

If (d^.Giatri <> c^.GiaTri) Then OK:= False Else

Begin

r^.Tiep:= Nil; d:= d^.Tiep; End;

End;

(26)

2 Xây dựng hàm Function KiemTra_DX(ds: Tro): Boolean; nhằm kiểm tra xem danh sách ds cho, có tồn cách xếp lại phần tử để cuối nhận danh sách đối xứng hay không? Viết phương án đệ quy lặp

Giải:

- Quản lí nút Tìm danh sách có nút chứa số giống - Nếu có: Loại cặp nút Lặp lại

(27)

ĐỀ 2006:

Type TroNut =^Nut;

Nut = Record

GiaTri: Integer;

Left, Right: TroNut; End;

Var T: Tro;

a.Tính chiều cao

Function ChieuCao(T: TroNut): Byte; Begin

If (T = Nil) Then ChieuCao:= Else

ChieuCao:= Max(ChieuCao(T^.Left), ChieuCao(T^.Right)) + 1; End;

b

Type TroNutDS = ^NutDS; NutDS = Record

GiaTri: Integer;

Muc: Byte; {lưu mức tương ứng} Next: TroNutDS;

End; Var F: TroNutDS;

Procedure Ghi(T: TroNut; Var F: TroNutDS; Level: Byte); Var

Begin

If (T <> Nil) Then Begin

New(p); p^.GiaTri:= T^.GiaTri; P^.Muc:= level;

P^.Next: = F; F:= p;

Ghi(T^.Left, F, Level + 1); Ghi(T^.Right, F, Level + 1); End;

End;

c Viết hàm đếm số nút DemSoNut(F: TroNutDS; Level: Byte): Integer; Function DemSoNut(F: TroNutDS; Level: Byte): Integer; Var p: TroNutDS; Dem: Integer;

Begin

p:= F;

While (p<> Nil) Begin

If (p^.Muc = level) Then Dem:= Dem + 1; P:= p^.Next;

End; DemSoNut:= Dem; End;

d Kiểm tra xem có phải nhị phân đầy đủ: Function LaCayNPDD(T: TroNut): Boolean;

Var Begin

H:= ChieuCao(T); SoNut:= 1;

For i:= to h –

SoNut:= SoNut*2; // Số nút tối đa mức Ghi(T, F, 1);

If (SoNut = DemSoNut(F,h) Then LaCayNPDD:= True Else

(28)

/* Bai tap 3_52 - In bieu thuc dang hau to cua mot bieu thuc trung to */ #include <stdio.h>

#include <conio.h> #define MAX 100

#define PLUS /* Dau cong */ #define MINUS /* Dau tru */ #define MULTIPLE /* Dau nhan */ #define DIVIDE /* Dau chia */

#define LPAREN /* Dau mo ngoac don */ #define RPAREN /* Dau dong ngoac don */ int top;

struct { int toantu; } stack[MAX]; void push (int tt) {

if (top < MAX-1)

stack[++top].toantu = tt; }

int isempty() {

return top == -1; }

int pop (int *tt) {

if (!isempty()) {

*tt = stack[top ].toantu; return 1;

}

return 0; }

int get (int *tt) {

if (!isempty()) {

*tt = stack[top].toantu; return 1;

}

return 0; }

void xet(int tt) {

char chuoi[] = "+-*/";

int uutien[] = {0,0,1,1,-1,-1}; int toantu, done = 0, val; if (isempty())

push(tt); else

{ {

if (get(&toantu)) {

(29)

{

pop(&toantu);

printf("%c ", chuoi[toantu]); }

else {

push(tt); done = 1; }

} else {

done = 1; push(tt); }

} while (!done); }

}

void in_hauto(char *expr) {

int len, i=0, ttu, done; char c, chuoi[]="+-*/"; top = -1;

len = strlen(expr); {

c = expr[i++];

while (c == ' ' && i < len-1) c = expr[i++];

switch (c) {

case '0' : case '1' : case '2' : case '3' : case '4' : case '5' : case '6' : case '7' : case '8' :

case '9' : printf("%c ", c); break; case '+' : xet(PLUS); break;

case '-' : xet(MINUS); break; case '*' : xet(MULTIPLE); break; case '/' : xet(DIVIDE); break; case '(' : push(LPAREN); break; case ')' : done = 0;

{

if (isempty()) {

done = 1;

printf("\n\nError\n"); }

else {

pop(&ttu);

if (ttu != LPAREN)

printf("%c ", chuoi[ttu]); else

done = 1; }

} while (!done); break;

(30)

} while (i < len); while (!isempty()) {

pop(&ttu);

printf("%c ", chuoi[ttu]); }

}

void main() {

char expr[50]; int done = 0;

printf("\nChuong trinh in bieu thuc hau to tuong ung voi mot bieu thuc" "trung to hop le"

"\nChu y :"

"\nCac toan hang chi tu den 9"

"\nCac toan tu chi gom + - * / ( )\n"); {

printf("\nNhap mot bieu thuc trung to hop le (trong de thoat): "); gets(expr);

if (strlen(expr) > 0) in_hauto(expr); else

done = 1; } while (!done); }

//Dem tong so nut la cua cay #include <stdio.h>

#include <alloc.h>

typedef int element_type; typedef struct node { element_type element; struct node *left, *right; } NODE;

NODE *root;

void khoi_tao_cay(NODE ** root) {

*root = NULL; }

void insert(NODE *tmp, NODE **root) {

if (tmp->element < (*root)->element) if ((*root)->left)

insert(tmp, &(*root)->left); else

(*root)->left = tmp; else

if ((*root)->right)

insert(tmp, &(*root)->right); else

(*root)->right = tmp; }

void insert_node(element_type e, NODE **root) {

(31)

tmp = (NODE *)malloc(sizeof(NODE)); tmp->element = e;

tmp->left = NULL; tmp->right = NULL; if (*root == NULL) *root = tmp; else

insert(tmp, root); }

void nhap_cay(NODE **root) {

element_type e; {

printf("\nNhap element (-1 de ket thuc) : "); scanf("%d", &e);

if (e != -1)

insert_node(e, root); } while (e != -1);

}

int dem_nut_la(NODE *root) {

if (root == NULL) return 0;

else

if (root->left != NULL || root->right != NULL)

return dem_nut_la(root->left) + dem_nut_la(root->right); else

return 1; }

void main() {

int tong_nut_la; khoi_tao_cay(&root); nhap_cay(&root);

tong_nut_la = dem_nut_la(root);

printf("\nTong so nut la = %d", tong_nut_la); getch();

(32)

Uses crt; Type

DS1 =^SN; SN = Record

info:integer; next:DS1; end;

DS2 =^TEN; TEN = Record

ten:string; dau:DS1; down:DS2; end;

Var

index:DS2; st,ten1:string; so:integer;

{****************************************************} Procedure Bosung(var index:ds2;so:integer;ten:string); Var p,q,tempo:DS2;

tam,tmp:DS1; Begin

new(tam); tam^.info:=so; tam^.next:=nil; p:=index;

while (p<>nil) and (p^.ten<ten) do begin

q:=p;

p:=p^.down; end;

if (p<>nil) and (p^.ten=ten) then begin

tmp:=p^.dau;

while tmp^.next<>nil do tmp:=tmp^.next; tmp^.next:=tam;

end else begin

new(tempo); tempộten:=ten; tempộdau:=tam; if p=index then begin

tempộdown:=index; index:=tempo;

end else begin

tempộdown:=p; q^.down:=tempo; end;

end; end;

{***********************************************} Procedure Inbang(index:ds2);

var p:ds2;tam:ds1; aa: string[10]; begin

writeln;

(33)

while p<>nil do begin

write(' ',p^.ten,' ':35-length(p^.ten)); tam:=p^.dau;

while tam<>nil do begin

str(tam^.info,aa);

write(tam^.info,' ': 5- length(aa)); tam:=tam^.next;

end;

p:=p^.down; writeln; end;

end;

(* - *) //Xoá tên học viên danh sách

Procedure Xoaten(var index: ds2;st: string); Var p,q: ds2;

Begin

p:= index;

While (p<> nil)and(p^.ten< st) do Begin

q:= p;

p:= p^.down; end;

If p = nil then Writeln('Khong co ten danh sach') else

if p= index then index:= index^.down else

q^.down:= p^.down; end;

(* - *) Procedure Xoa(var index: ds2; st: string;so: integer);

Var tam,p1: ds1; p,q: ds2; Begin

p:= index;

While (p <> nil) and (p^.ten < st ) do Begin

q:= p;

p:= p^.down; end;

If p = nil then Writeln('Khong co ten danh sach') else

begin

tam:= p^.dau;

While (tam <> nil)and( tam^.info <> so) do Begin

p1:= tam;

tam:= tam^.next; end;

If tam = nil then writeln('Khong co so trang ten nay') else

if tam= p^.dau then p^.dau:= p^.dau^.next else

p1^.next:= tam^.next; end;

end;

(34)

Procedure Sapxep(var index: ds2); Var p1,q1: ds1;

tam: integer; p: ds2;

Begin

p:= index;

While p<> nil do Begin

p1:= p^.dau;

While p1^.next <> nil do Begin

q1:= p1^.next; While q1 <> nil do

Begin

If p1^.info > q1^.info then Begin

tam:= p1^.info; p1^.info:= q1^.info; q1^.info:= tam; end;

q1:= q1^.next; end;

p1:= p1^.next; end;

p:= p^.down; end;

end;

(* -*) { Thu tuc dem xem co bao nhieu trang xuat hien cua ten: '}

Procedure Demst(var index: ds2); Var dem: byte;

p,q: ds2; p1: ds1; Begin

Writeln(' TEN SO LAN XUAT HIEN '); p:= index;

While p<> nil do Begin

p1:= p^.dau; Dem:= 1;

While p1^.next <> nil do Begin

dem:= dem+ 1; p1:= p1^.next; end;

Writeln(' ', p^.ten,' ':35-length(p^.ten),dem); p:= p^.down;

end; end;

BEGIN {CHUONG TRINH CHINH} Repeat

write('Nhap ten :');readln(st); if st<>'' then

begin repeat

write('Nhap so trang :');readln(so); if so>0 then bosung(index,so,st); until so<=0;

end; until st='';

Ngày đăng: 23/05/2021, 11:09

TỪ KHÓA LIÊN QUAN

TÀI LIỆU CÙNG NGƯỜI DÙNG

TÀI LIỆU LIÊN QUAN

w