map display reverse buffer else loop + i 1 begin display "ERROR: dot is the end of command!" newline loop 0 empty-stack lineeditor "XY$abce#def." --> abcdef... s file let doublet cons s
Trang 11
Trang 3CH NG V C U TRÚC D LI U
a bi t r ng vi c l p trình ph thu c ph n l n vào cách mô hình hoá d li u c a bài toán
c n gi i M i quan h gi a thu t toán và c u trúc d li u trong l p trình đã đ c Niclaus Wirth, tác gi ngôn ng l p trình Pascal, đ a ra m t công th c r t n i ti ng :
T
(Data structure + Algorithms = Programs)
Nh đã th y, thu t toán m i ch ph n ánh các thao tác c n x lý, còn đ i t ng đ x lý trong máy tính l i là d li u Nói đ n thu t toán là nói đ n thu t toán đó tác đ ng lên d li u nào Còn nói đ n d li u là nói đ n d li u y c n đ c tác đ ng b i thu t toán nào đ đ a
đ n k t qu mong mu n D li u bi u di n thông tin c n thi t đ gi i bài toán, g m d li u
đ a vào, d li u đ a ra và d li u tính toán trung gian M t c u trúc d li u liên quan đ n ba
y u t : ki u d li u, các phép toán tác đ ng lên d li u và cách bi u di n d li u trong b
nh c a máy tính tu theo công c l p trình
Trong ch ng này, chúng ta s trình bày m t s c u trúc d li u tiêu bi u nh t p h p,
h p ch đ c li t kê m t l n và không đ c s p x p th t nên ng i ta không nói đ n ph n
t th nh t, ph n t th hai, v.v Ví d hai t p h p sau đây là đ ng nh t :
{ a, b, d, a, d, e, c, d } = { a, b, c, d }
Do t p h p c ng là m t danh sách, ng i ta có th s d ng c u trúc danh sách đ bi u
di n t p h p trong Scheme Nh v y, m t t p h p r ng là m t danh sách r ng so sánh hai
t p h p có b ng nhau không, ta có th s d ng v t equal? nh sau :
(define (setequal? E1 E2)
(cond ; hai t p h p r ng thì b ng nhau
((and (null? E1) (null? E2)) #t)
; hai t p h p có hai ph n t đ u tiên b ng nhau
1 Khái ni m đ i t ng c a t p h p có tính tr c giác, do nhà toán h c ng i c G Cantor đ a ra t n m 1985
n n m 1902, nhà tri t h c ng i Anh B Russell đã ch ra nh ng ngh ch lý toán h c (paradox) hay nh ng
mâu thu n lôgic trong lý thuy t t p h p
147
Trang 4((equal? (car E1) (car E2))
(setequal? (cdr E1) (cdr E2)))
; hai t p h p có hai ph n t đ u tiên khác nhau thì khác nhau !!!
(else #f))) (setequal? ’(1 3 4 5 6) ’(1 3 4 5 6))
ý r ng trong v t setequal? trên đây, ta ch a x lý hai t p h p có các ph n t
gi ng y nhau và có cùng s ph n t , nh ng không đ c s p x p th t nh nhau :
(setequal? '(1 5 4 3 6) '(1 3 4 5 6))
> #f
Sau đây ta s s d ng th ng xuyên hàm member đ x lý t p h p Hàm này ki m tra
m t ph n t có thu c m t danh sách đã cho hay không :
> #t
xây d ng m t t p h p t m t danh sách, ng i ta ph i lo i b các ph n t trùng l p Hàm list->set sau đây s d ng hàm member l n l t ki m tra các ph n t c a danh sách đã cho K t qu tr v ch gi l i ph n t cu i cùng đ i v i nh ng ph n t trùng nhau và
ch a s p x p l i các ph n t theo th t (xem ph ng pháp s p x p nhanh cu i ch ng) (define (list->set L)
(cond ((null? L) ’())
((member (car L) (cdr L))
(list->set (cdr L))) (else (cons (car L)
(list->set (cdr L))))) (list->set ’(a b d a d e c d))
> ’(b a e c d)
(define (union2 E1 E2)
(cond ((null? E1) E2)
Trang 5((member (car E1) E2) (union2 (cdr E1) E2)) (else (cons (car E1) (union2 (cdr E1) E2)))))
((null? E1) E2)
; n u t p h p th nh t có ph n t thu c t p h p th hai thì b qua ((member (car E1) E2) (union2 (cdr E1) E2))
; ti p t c sau khi gi m kích th c t p h p th nh t (else (cons (car E1) (union2 (cdr E1) E2))))) (union2 ’(1 2 3 7) ’(2 3 4 5 6))
> ’(1 7 2 3 4 5 6)
M r ng phép h p c a hai t p h p, ta xây d ng phép h p trên các t p h p b t k b ng
cách s d ng hàm list-it đã đ c đ nh ngh a ch ng tr c :
(define (union Lset)
(list-it union2 Lset ’()))
(union ’(1 2 3 4) ’(2 3 4 5 6) ’(4 5 6 7) ’(6 7 8))
> ’(1 2 3 4 5 6 7 8)
2 Phép giao trên các t p h p
T ng t cách xây d ng phép h p trên các t p h p b t k , tr c tiên ta xây d ng phép
giao c a hai t p h p E 1 ∩E 2 nh sau :
(define (intersection2 E1 E2)
(cond ; n u m t t p h p là r ng thì k t qu c ng r ng
((null? E1) E1)
; ch n ra ph n t n m c hai t p h p ((member (car E1) E2) (cons (car E1) (intersection2 (cdr E1) E2)))
; ti p t c sau khi gi m kích th c t p h p th nh t (else (intersection2 (cdr E1) E2)))) (intersection2 ’(1 2 3 4)’(2 3 4 5 6))
> ’(2 3 4)
M r ng phép giao c a hai t p h p, ta xây d ng phép giao trên các t p h p b t k b ng
cách s d ng hàm apply đã đ c đ nh ngh a m c Error! Reference source not found :
(define (intersection Lset)
(cond ; giao c a các t p h p r ng c ng là r ng
((null? Lset) ’())
; giao c a m t t p h p là chính nó ((null? (cdr Lset)) (car Lset))
; đ a v th c hi n phép giao c a hai t p h p (else (intersection2
(car Lset) (apply intersection (cdr Lset))))))
Trang 6(intersection ’(1 2 3 4) ’(2 3 4 5 6) ’(4 5 6 7))
> ’(4)
3 Phép hi u c a hai t p h p
Cho hai t p h p E 1 và E 2 , ta âënh nghéa phép hi u c a hai t p h p E 1 \E 2 nh sau :
(define (difference E1 E2)
(cond ; n u E2 r ng thì k t qu là E 1
((null? E2) E1)
; n u E1 r ng thì k t qu là r ng ((null? E1) ’())
; n u E1 có ph n t thu c E 2 thì b qua ((member (car E1) E2)
(difference (cdr E1) E2))
; ti p t c sau khi gi m kích th c t p h p E 1
(else (cons (car E1)
(difference (cdr E1) E2))))) (difference ’(1 2 3 4 5) ’(1 2))
> ’(3 4 5)
4 Tìm các t p h p con c a m t t p h p
Cho tr c t p h p E, ta c n tìm t p h p t t c các t p h p con (sub-set) c a E, ký hi u 2 E
Ch ng h n cho E={ a, b, c } thì 2 E ={ ∅, {a}, {b}, {c}, {a, b}, {a, c}, {b, c}, {a, b, c}} có t t c
8 ph n t bao g m t p h p r ng và b n thân t p h p E
N u t p h p E r ng, thì 2 E c ng r ng N u E khác r ng, xét m t ph n t a∈E, khi đó có
các t p h p con ch a a và các t p h p con không ch a a u tiên xây d ng t p h p E\{a},
sau đó, chèn a vào t t c các t p h p con c a E\{a} Ta có hàm subset nh sau :
(define (subset E)
(if (null? E)
(list ’()) (let ((Lremain (subset (cdr E)))) (append Lremain
(map (lambda (L)
(cons (car E) L)) Lremain))))) (subset ’(a b c))
> ’(() (c) (b) (b c) (a) (a c) (a b) (a b c))
Danh sách ki u «ng n x p» (stack), còn đ c g i là «ch ng» (t ng t m t ch ng đ a,
m t b ng đ n ), là m t c u trúc d li u mà phép b sung hay lo i b m t ph n t luôn luôn
đ c th c hi n m t đ u g i là đ nh (top) Nguyên t c ho t đ ng «vào sau ra tr c» c a
ng n x p đã d n đ n m t tên g i khác là danh sách ki u LIFO (Last In First Out)
Ng n x p đ c s d ng r t ph bi n trong tin h c Hình V.1 minh ho ho t đ ng c a m t
ng n x p khi th c hi n th t c đ quy tính n!
Trang 7push-stack : T × Stack(T) → Stack(T)
pop-stack : Stack(T) -/→ Stack(T)
fac(3)= ? fac(3)=3*fac(2) fac(2)=2*fac(1) fac(1)=1*fac(0)
2*fac(1) 1*fac(0) fac(0)=1
3*fac(2) 2*fac(1) fac(1)=?
3*fac(2) fac(2)=?
Ta c n xây d ng các hàm Scheme thao tác trên ng n x p nh sau :
(empty-stack? (empty-stack))
#t
Trang 8b m t ph n t đ c th c hi n m t đ u danh sách Trong Scheme, m i l n b sung m t
ph n t vào danh sách kéo theo vi c t o ra m t b đôi (dotted pair) m i
(empty-stack? (push-stack 'a (empty-stack)))
> #f
(pop-stack (push-stack ’a ’(1 2 3)))
> ’(1 2 3)
Trang 9(pop-stack (push-stack ’a ’(1 2 3)))
> 3
V.2.3 Xây d ng trình so n th o v n b n
Sau đây là m t ví d đ n gi n minh ho ng d ng ng n x p đ xây d ng m t trình so n
th o đ n gi n cho phép th c hi n vào ra t ng dòng v n b n m t Ho t đ ng nh sau : hàm
nh n dòng vào là m t tham bi n đ l u gi trong m t vùng nh trung gian (buffer) Dòng vào
ch a các ký t h n h p mà m t ký t nào đó có th là m t l nh so n th o (edit command)
Có b n lo i ký t nh sau :
• Các ký t khác ba ký t #, $ và newline đ u là ký t v n b n đ đ c l u gi trong
vùng nh trung gian
• Ký t # dùng đ xoá ký t đ ng tr c trong vùng nh trung gian
• Ký t $ dùng đ xoá t t c ký t trong vùng nh trung gian
• Ký t qua dòng newline đ k t thúc m t dòng vào và đ a n i dung vùng nh trung
gian lên màn hình
Ta s s d ng m t ng n x p đ bi u di n vùng nh trung gian Trong ch ng trình có s
d ng m t hàm c c b loop đ đ c các ký t liên ti p t dòng vào Ch s i là ký t đang đ c
((#\#) (loop (+ i 1) (pop-stack buffer))) ((#\$) (loop (+ i 1) (empty-stack)))
((#\.) (map (display (reverse buffer))) (else (loop (+ i 1)
(begin (display "ERROR: dot is the end of command!")
(newline)))))) (loop 0 (empty-stack)))))
(lineeditor "XY$abce#def.")
> abcdef
Trang 10Ng i đ c có th phát tri n trình so n th o trên đây đ x lý các tình hu ng so n th o v n
b n ph c t p h n
V.2.4 Ng n x p đ t bi n
Ta mu n r ng ho t đ ng c a ng n x p g n g i v i các ch ng (pile) h n, ngh a là vi c b sung lo i b ph n t ch liên quan đ n m t ch ng đ ta có th gán cho bi n Ta xây d ng ki u
d li u tr u t ng ng n x p đ t bi n (mutable stack) Stack!(T) (sau tên có m t d u ch m
than) nh sau :
Types Stack!(T)
functions
empty-stack!? : Stack!(T) → boolean
push-stack! : T × Stack!(T) → Stack!(T)
phân bi t v i các ng n x p đã xét, ta thêm vào sau các tên ki u và hàm m t d u ch m
than ! t ng t các đ t bi n i m ho t đ ng khác bi t c a ng n x p đ t bi nlà sau khi lo i
b m t ph n t thì hàm tr v ph n t trên đ nh
Trong ch ng tr c, khi xét môi tr ng làm vi c c a Scheme, ta th y r ng không th s
d ng l nh set! đ thay đ i n i dung c a ng n x p ch ng h n nh :
(define (push-stack x s)
(set! s (cons x s)) s)
Ta ph i áp d ng tính ch t đ t bi n c a các danh sách, b ng cách bi u di n ng n x p r ng (empty stack) b i m t danh sách khác r ng đ sau đó thay đ i b i cdr
(define (empty-stack!) (list ’stack!))
(define (empty-stack!? S)
(and (pair? S)
(null? (cdr S)) (eq? ’stack! (car S)))) (define S1 (empty-stack!))
S1 ; xem n i dung c a ng n x p
> ’(stack!)
(empty-stack!? S1)
> #t
b sung (push) và lo i b (pop) trên ng n x p S, ta gi thi t r ng bi n S luôn luôn tr
đ n cùng m t b đôi T t c các thao tác v t lý đ c th c hi n nh l nh cdr nh minh ho trong hình d i đây
Lúc ng n x p r ng, danh sách S ch ch a ph n t ’stack! Sau khi b sung ph n t
’bob thì ph n t này đ ng th hai (ngay sau ’stack!) trong danh sách S
Ta xây d ng hàm nh sau :
(define (push-stack! x S)
(set-cdr! S (cons x (cdr S))))
Trang 11(cadr S))) (top-stack! S1)
> 'jim
(define (pop-stack! S)
(if (empty-stack!? S)
(begin (display "ERROR: stack! is empty!") (newline)) (let ((top (cadr S)))
(set-cdr! S (cddr S)) top)))
Trang 12((empty-stack!?) (null? content)) ((push-stack!)
((top-stack!) (if (null? content) (begin
(display "ERROR: stack is empty!") (newline))
(car content)))))))
; Ki m tra ng n x p r ng nh thông đi p ’empty-stack!?
(define (empty-stack!? S) (S ’empty-stack!?))
; B sung m t ph n t vào ng n x p nh thông đi p ’push-stack!
(define (push-stack! x S) (S ’push-stack! x))
; Lo i b m t ph n t kh i ng n x p nh thông đi p ’pop-stack!
(define (pop-stack! S) (S ’pop-stack!))
; X lý ph n t đ nh c a ng n x p nh thông đi p ’top-stack!
(define (top-stack! S) (S ’top-stack!))
Trang 13(9 + 2) * 52
Tuy nhiên, trong b nh , các bi u th c đ c bi u di n d ng cây (ta s xét c u trúc cây
trong m c ti p theo) Khi tính toán, bi u th c s h c d ng cây nh phân (cho các phép toán
hay hàm, g i chung là toán t , có t i đa hai toán h ng) đ c đ a ra thành m t chu i ký t
d ng h u t (d ng ký pháp Ba Lan) nh sau :
9 2 52 + *
Lúc này các d u ngo c không còn n a do các bi u th c d ng h u t th ng không nh p
nh ng (un-ambiguous) Khi đ c bi u th c t trái qua ph i, ta g p các toán h ng tr c khi g p
m t toán t N u áp d ng toán t này cho các toán h ng tr c đó, ta nh n đ c m t k t qu
là m t toán h ng m i và quá trình ti p t c theo đúng ch đ «vào tr c ra sau» Do v y,
ng i ta s d ng m t ng n x p đ mô ph ng quá trình tính toán bi u th c : các toán h ng
(đ c đ c t bi u th c h u t , l n l t t trái qua ph i) đ c «đ y vào» ng n x p cho đ n khi
g p toán t Th c hi n phép toán vói các toán h ng «l y ra» t ng n x p r i l i đ y k t qu
vào ng n x p cho đ n khi h t bi u th c và l y k t qu n m đ nh ng n x p
Sau đây ta xây d ng hàm tính m t bi u th c s h c d ng h u t (ng i đ c có th tìm đ c
các giáo trình «C u trúc d li u và thu t toán» đ hi u chi ti t h n) Ch ng trình s d ng
ng n x p đ t bi n x lý các phép toán s h c +, -, *, / và hàm sqrt :
(define (evaluation postfix-expr)
(let ((pile (make-empty-stack!)))
(letrec ((compute
(lambda (exp) (if (null? exp) (top-stack! pile) (let ((s (car exp))) (if (number? s) (push-stack! s pile) (begin
(case s ((sqrt) (let ((v (pop-stack! pile))) (push-stack! (sqrt v) pile))) ((+)
(let ((v2 (pop-stack! pile)) (v1 (pop-stack! pile)))
(push-stack! (+ v1 v2) pile))) ((*)
(let ((v2 (pop-stack! pile)) (v1 (pop-stack! pile)))
(push-stack! (* v1 v2) pile))) ((-)
(let ((v2 (pop-stack! pile)) (v1 (pop-stack! piler))) (push-stack! (- v1 v2) pile))) ((/)
(let ((v2 (pop-stack! pile)) (v1 (pop-stack! pile)))
(push-stack! (/ v1 v2) pile)))) (compute (cdr exp)))))))))
(compute postfix-expr))))
Trang 14(evaluation ’(9 2 + 52 sqrt *))
> 79.3221
V.3.1 C u trúc d li u tr u t ng ki u t p
C u trúc d li u ki u t p (file) mô ph ng m t hàng đ i (queue) có ch đ ho t đ ng theo
ki u «vào tr c ra tr c» FIFO (First In First Out) Lúc này phép b sung đ c th c hi n
empty-file? : File(T) → boolean
push-file : T × File(T) → File(T)
Sau đây ta xây d ng các hàm x lý t p s d ng ki u danh sách c a Scheme Vi c b sung
Trang 15(begin (display "ERROR: file is empty!") (newline))
(cdr F))) (define (top-file F)
(if (empty-file? F)
(begin (display "ERROR: file is empty!") (newline))
(car F)))
Ta nh n th y r ng vi c s d ng danh sách là không h p lý khi kích th c t p t ng lên và
l nh appenf trong hàm push-file s gây ra chi phí tính toán l n
V.3.2 Ví d áp d ng t p
Sau đây ta xét m t ví d áp d ng c u trúc d li u ki u t p v a xây d ng Gi s cho tr c
m t danh sách L g m các s nguyên t ng ng t và m t s nguyên N, ta c n tính s l ng các
c p s (x, x + N) v i x và N có m t trong danh sách
Ch ng h n n u L = (0 2 3 4 6 7 8 9 10 12 13 14 16 20) và N = 8, thì ta tìm đ m đ c b n
c p s tho mãn nh sau : (2, 10), (4, 12), (6, 14) và (12, 20)
Ph ng pháp đ n gi n nh t có tính tr c quan là v i m i s x l y t L, ti n hành tìm ki m
các s x + N trong L Tuy nhiên ph ng pháp này có chi phí l n vì ta ph i duy t qua duy t
l i nhi u l n danh sách L Sau đây là ph ng pháp ch c n duy t m t l n danh sách L
Ta s d ng t p F có đ dài < N và ki m tra m i ph n t x c a F :
• N u t p F r ng thì ta ch vi c thêm vào ph n t x
• N u top là ph n t đ u t p và x > top + N, ta ch c ch n r ng ta không th còn tìm đ c
ph n t y nào c a F mà y = top + N và do v y ta ph i lo i b F
• N u x = top + N, ta lo i b x kh i L đ thêm x vào F và đ m c p tho mãn (x, top)
• N u x < top + N, ta ch lo i b x kh i L đ thêm x vào F
(cdr L) result (push-file (car L) F))) (else
(let ((difference (- (car L) (top-file F)))) (cond
((< N difference) (count L result (pop-file F))) ((= N difference)
Trang 16(count (cdr L) (+ result 1) (pop-file (push-file (car L) F)))) (else
(count (cdr L) result (push-file (car L) F)))))))))) (count L 0 (empty-file))))
push-file! : T × File!(T) → File!(T)
pop-file! : File!(T) → File!(T)
Ta có th áp d ng k thu t xây d ng các ng n x p đ t bi n cho c u trúc d li u ki u t p
đ t bi n Ta s không s d ng l nh append đ b sung ph n t m i vào t p mà s d ng m t con tr tr đ n đuôi c a t p V i cách xây d ng này, đ dài t p s không bi t gí i h n
Nh v y, c u trúc t p có d ng m t b đôi (dotted pair) mà thành ph n car tr đ n danh sách các ph n t là n i dung t p, còn thành ph n cdr tr đ n ph n t b đôi cu i cùng c a danh sách này
(define (empty-file!)
(cons '() '()))
(define (empty-file!? file)
(null? (car file)))
Trang 17(define (push-file! s file)
(let ((doublet (cons s '())))
(if (null? (car file))
(set-car! file doublet) (set-cdr! (cdr file) doublet)) (set-cdr! file doublet)))
file file
(define (top-file! file)
(if (empty-file!? file)
(begin (display "ERROR: file is empty!") (newline))
(caar file))) (define (pop-file! file)
(if (empty-file!? file)
(begin (display "ERROR: file is empty!") (newline))
(begin (set-car! file (cdar file)))))
Sau đây là v n d ng xây d ng t p có n i dung ’(ann bob jim) :
Trang 18V.4 Cây
có nút nào thì đ c g i là cây r ng (empty tree)
Khi cây khác r ng, nút trên cùng, cao nh t, là nút g c (root node) Phía d i nút g c có
th có nhi u nút con (child node) n i v i nó b i các c nh (edge) Lúc này, nút g c là nút cha
(father node) M i nút con l i có th là m t nút cha có nhi u nút con n i v i nó, và c th ti p
t c Ph n cây t o ra t m t nút con b t k là cây con (subtree)
Nh ng nút m c th p nh t không có nút con nào n i v i nó là lá (leaf) hay nút ngoài (exterior node) M t nút không ph i là lá là nút trong (interior node) Các nút con có cùng cha
là các nút anh em (siblings) M i nút c a cây có m t cha duy nh t (tr nút g c), là h u du hay con cháu (descendant) c a nút g c và là t tiên (ancestor) c a các nút lá M t nhánh
(branch) hay m t đ ng đi (path) là t p h p các nút và các nhánh xu t phát t m t nút đ n
m t nút khác
Trong toán h c, cây là m t đ th (graph) liên thông không có chu trình Trong m t cây, luôn luôn t n t i duy nh t m t đ ng đi t nút g c đ n m t nút b t k , ho c gi a hai nút nào
đó đã cho Nh v y, m t cây có th r ng, ho c ch có m t nút g c, ho c g m m t nút g c và
m t ho c nhi u cây con
C u trúc cây đ c ng d ng nhi u trong tin h c : t ch c th m c c a các h đi u hành Unix, MS-DOS, , m t ch ng trình Scheme, cây gia ph ,
G c
C nh Nút trong
Lá (nút ngoài)
Hình V.7 Hình nh cây
Sau đây ta s xét cách Scheme x lý các c u trúc d li u d ng cây, tr c tiên là cây nh
3 Ch nh ng đ i t ng đ c đ nh ngh a b i hai quy t c trên đây m i là các cây nh phân
ki u T
Trang 19N u A = (E, A1, A2) là cây nh phân, thì E là nút g c, A1 là cây con bên trái, A2 là cây
con bên ph i c a A N u A là cây suy bi n ch g m m t nút, thì nút đó luôn luôn là nút g c
c a m t cây con Ng i ta còn g i A là cây đ c g n nhãn (labelled tree, hay tag tree) b i
các giá tr trong T Hình d i đây minh ho hai cây nh phân, m t cây bi u di n bi u th c s
h c x+(y-3*z)/4 và m t cây bi u di n m t s-bi u th c nh sau :
Hình V.8 Hai cây nh phân bi u di n : a) bi u th c s h c ; b) bi u th c Scheme
Chú ý s l ch đ i x ng c a đ nh ngh a : n u A không ph i là cây r ng, thì cây (E, A, 0)
khác v i cây (E, 0, A) C n phân bi t m t nút v i m t giá tr g n cho nút đó Các nút luôn
luôn r i (phân bi t) nhau, còn các giá tr thì có th gi ng nhau Ví d , cây bi u di n s-bi u
th c c a Scheme trong hình V.9.(b) trên có 7 nút, trong khi đó ch có 6 giá tr phân bi t
nhau gán cho chúng Ng i ta đ a ra n m lo i cây nh phân đ c bi t nh sau :
1 Cây suy thoái (degenerated hay filiform tree) m i nút ch có đúng m t con không r ng
2 Cây hình l c trái (left comb) có m i con bên ph i là m t lá
3 Cây đ y đ (complete tree) có m i m c c a cây đ u đ c làm đ y
4 Cây hoàn thi n (perfect tree) m i m c c a cây đ u đ c làm đ y, tr m c cu i cùng,
empty-tree? : BinTree(T) → boolean
create-tree : T × BinTree(T) × BinTree(T) → BinTree(T)
leaf? : BinTree(T) → boolean (có th không c n)
Trang 20empty-tree?(create-tree(E, A1, A2)) = false
root(create-tree(E, A1, A2)) = E
left(create-tree(E, A1, A2)) = A1
right(create-tree(E, A1, A2)) = A2
leaf?(A) <=> empty-tree?(left(A)) và empty-tree?(right(A))
V.4.1.2 Bi u di n cây nh phân
1 Bi u di n ti t ki m s d ng hai phép cons
; nh ngh a cây r ng :
(define empty-tree ()) ; ho c
(define empty-tree (list))
; nh ngh a v t ki m tra cây có r ng không :
(define empty-tree? null?)
; nh ngh a cây khác r ng (E, A1, A2) :
(define (create-tree E A1 A2)
(cons E (cons A1 A2)))
; nh hàm tr v nút g c :
(define root car)
; nh hàm tr v cây con trái :
(define left cadr)
(create-tree 2 empty-tree empty-tree)
(create-tree 3 empty-tree empty-tree))
(create-tree 4 empty-tree empty-tree)
(create-tree 5 empty-tree empty-tree))
(create-tree 3 empty-tree empty-tree))
> ’(1 (2 (4 ()) 5 ()) 3 ())
Trang 212 Bi u di n d ng đ y đ
d dàng x lý khi l p trình, thông th ng ng i ta bi u di n cây d ng danh sách, đ y
đ các nút, s d ng 3 phép cons :
(define empty-tree ())
(define empty-tree? null?)
(define (create-tree E A1 A2)
(list E A1 A2))
(define root car)
(define left cadr)
(define right caddr)
(define (leaf? A)
(and (null? (cadr A)) (null? (caddr A))))
; Ví d t o m t cây nh phân có 3 nút :
(create-tree 1 (create-tree 2 empty-tree empty-tree)
(create-tree 3 empty-tree empty-tree))
> ’(1 (2 () ()) (3 () ()))
Cây A trong Hình V.10 trên đây đ c đ nh ngh a nh sau :
(create-tree 1 (create-tree 2 (create-tree 4 empty-tree empty-tree)
(create-tree 5 empty-tree empty-tree))
(create-tree 3 empty-tree empty-tree))
> (1 (2) (4 () ()) (5 () ())) (3 () ()))
Trong d ng đ y đ , m i nút lá A đ u đ c bi u di n d ng (A () ())
3 Bi u di n đ n gi n
Khi ki u các ph n t không ch a các b đôi, k c không ch a danh sách, m t lá có th
đ c bi u di n đ n gi n b i giá tr c a nút, mà không c n cons Ta đ nh ngh a l i nh sau :
(define empty-tree ())
(define empty-tree? null?)
(define (create-tree E A1 A2)
(if (and (null? A1) (null? A2))
Trang 22Cây A trong Hình V.10 trên đây đ c đ nh ngh a nh sau :
(create-tree 1
(create-tree 2
(create-tree 4 empty-tree empty-tree)
(create-tree 5 empty-tree empty-tree))
(create-tree 3 empty-tree empty-tree))
> ’(1 (2 4 5) 3)
Trong d ng đ n gi n này, các nút c a cây A đ c bi u di n b i giá tr c a nút l n l t
theo th t duy t cây g c−trái−ph i
V.4.1.3 M t s ví d l p trình đ n gi n
Xây d ng hàm size có d ng hàm nh sau :
; size : BinTree(T) → Integer
cao c a m t cây khác r ng là s c nh t i đa n i g c c a cây v i các lá c a nó
Theo quy c, đ cao c a m t cây r ng có th là −1 Xây d ng hàm height có d ng nh sau :
; height : BinTree(T) → Integer
(define (height A)
(if (empty-tree? A)
-1 (+ 1 (max (height (left A)) (height (right A))))))
; cao c a cây A Hình V.10.:
Trang 23n n
C
n + cây nh phân kích th c n,
v i C n p là t h p ch p p (cách ch n p ph n t ) c a n (trong s n ph n t )
C hai hàm size và height trên đ u có chi phí tuy n tính theo n
V.4.1.4 Duy t cây nh phân
Cây đ c s d ng ch y u đ t ch c l u tr d li u nên khi c n khai thác ng i ta ph i
đ c xây d ng đ quy, m t cách t nhiên, ch ng trình duy t cây có th s d ng đ quy M i
chi n l c duy t cây đ u tr v k t qu là danh sách các nút đã đ c duy t qua
Ta s xét sau đây chi n l c duy t cây nh phân theo chi u sâu Trong tr ng h p t ng
quát, thu t toán có d ng nh sau :
m t ph n t c a cây A (liên quan đ n n i dung hay nhãn c a nút v a đ c duy t) Th t
duy t cây trên đây (g c-trái-ph i) là th t tr c hay còn đ c g i là th t ti n t (prefixe
order) N u đ i l i th t duy t trên đây thì ta nh n đ c :
− Th t gi a hay trung t (infixe order) n u nút g c đ c x lý gi a các l i g i đ quy
(trái-g c-ph i)
− Th t sau hay h u t (postfixe order) n u nút g c đ c x lý sau các l i g i đ quy
(trái-ph i-g c)
Tuy nhiên, ta c ng có th có thêm ba th t duy t cây theo h ng ng c l i là : g c-ph
i-trái, ph i-g c-trái và ph i-trái-g c
Ví d hàm nodes sau đây duy t cây nh phân đ tr v danh sách t t c các nút c a cây
đó Do hàm s d ng l nh append nên có chi phí b c hai đ i v i kích th c c a cây
; nodes: BinTree(T) → List(T)
; Duy t cây nh phân theo th t tr c :
(define (pre-nodes A)
Trang 24(if (empty-tree? A)
’()
(append (list (root A))
(pre-nodes (left A)) (pre-nodes (right A)))))
; Duy t cây nh phân theo th t gi a :
(define (inf-nodes A)
(if (empty-tree? A)
’()
(append (inf-nodes (left A))
(list (root A)) (inf-nodes (right A)))))
; Duy t cây nh phân theo th t sau :
(define (post-nodes A)
(if (empty-tree? A)
’()
(append (post-nodes (left A))
(post-nodes (right A)) (list (root A))))) minh ho các thu t toán duy t cây trên đây, gi s A là cây đ c cho nh hình sau :
(create-tree 6 empty-tree empty-tree)
(create-tree 7 empty-tree empty-tree)))
Trang 25V.4.2 C u trúc cây t ng quát
Trong tr ng h p cây t ng quát, m i nút đ u đ c g n nhãn và có s l ng cây con tu ý
không h n ch M t cách tr c giác, cây có g n nhãn là m t c u trúc d li u g m m t giá tr
nhãn và m t danh sách có th r ng các cây con g n nhãn Nh v y cây không bao gi r ng,
nh ng danh sách các cây con có th r ng Trong tr ng h p cây ch có m t con, thì không có
khái ni m cây con trái hay cây con ph i Ta c ng c n chú ý r ng c u trúc cây nh phân không
ph i là tr ng h p riêng c a cây t ng quát
Cho tr c t p h p các cây ki u T V i m i cây T, các cây T 1 , , T n đ c g i là con c a T
M t nhãn e nào đó là g c c a T S con m i nút là b c (degree) c a nút đó M t nút có có
create-tree : T × Forest(T) → Tree(T)
var F: Forest(T); A, E: Tree(T)
preconditions
car(F) và cdr(F) ch xác đ nh khi và ch khi F ≠ ()
(define create-tree cons)
(define root car)
Trang 26(if (pair? A)
(car A) A)) (define (forest A)
(if (pair? A)
(cdr A)
’())) (define (leaf? A)
(not (pair? A)))
Ch ng h n cây A trên đây đ c bi u di n b i :
Hàm tree-size đ m s l ng các nút trong cây :
; tree-size : Tree(T) → Integer
(define (tree-size A)
(define (size-forest F)
Trang 27(if (null? F)
1 (+ 1 (tree-size (car F)) (size-forest (cdr F))))) (size-forest (forest A)))
(define A '(1 2 (3 5) (4 6 7)))
(tree-size A)
> 13
2 Tính đ cao c a cây
Hàm tree-height tính đ cao c a cây :
; tree-height : Tree(T) → Integer
(define (tree-height A)
(define (height-forest F hmax)
(if (null? F)
hmax (height-forest (cdr F) (+ 1 (max (tree-height (car F)) hmax))))) (height-forest (forest A) 0))
(define A '(1 2 (3 5) (4 6 7)))
(tree-height A)
> 3
V.4.2.4 Duy t cây t ng quát không có x lý trung t
Chi n l c duy t cây t ng quát tìm danh sách các nút g m phép duy t theo th t tr c
và phép duy t theo th t sau, không có th t trung t
Thu t toán duy t cây theo th t tr c : t i m i b c đ quy, s d ng l nh append
đ t o danh sách là nút g c và k t qu duy t các cây con c a r ng :
; pre-nodes: Tree(T) → List(T)
(define (pre-nodes A)
(define (nodes-forest F)
(if (null? F)
’() (append (pre-nodes (car F))
(nodes-forest (cdr F))))) (append (list (root A)) (nodes-forest (forest A))))
Thu t toán duy t cây theo th t sau : t ng t phép duy t theo th t tr c nh ng phép
(nodes-forest (cdr F))))) (append (nodes-forest (forest A)) (list (root A))))
Trang 28Ví d cho cây A g m 11 nút s d ng ph ng pháp bi u di n cây đ n gi n qua các lá :
Trong quá trình phân tích cú pháp (đ biên d ch mã ngu n thành mã đích), ng i ta s
d ng m t b ng d li u l u gi thông tin liên quan đ n phép toán và tham s t ng ng B ng này cung c p các c p giá tr g m nút và s l ng các cây con t ng ng đ ki m tra tính đúng đ n c a bi u th c
Thông th ng ng i ta s d ng các giá tr nút d ng nguyên t (atom) Ng i ta th ng
u tiên s d ng cách bi u di n đ n gi n cây t ng quát qua các lá Khi bi t đ c s l ng các con c a m t nút, ng i ta dùng các phép toán ti p c n đ n cây con th n, ti p c n đ n các
phép toán c s , c ng nh ti p c n đ n các c u trúc d li u đã đ c đ nh ngh a trong mã ngu n
Sau đây là m t s đ nh ngh a hàm t o các cây cú pháp :
; nh ngh a cây ch g m m t nút
(define (create0 E) E)
; Cây g m m t nút và m t cây con
(define (create1 E A) (list E A))
; Cây g m m t nút và hai cây con
(define (create2 E A1 A2) (list E A1 A2))
v.v
; Hàm tr v cây con th nh t v i đi u ki n cây đã cho có t i thi u 1 con
Trang 29(define son1 cadr)
; Hàm tr v cây con th hai v i đi u ki n cây đã cho có t i thi u 2 con
(define son2 caddr)
; Hàm tr v cây con th ba v i đi u ki n cây đã cho có t i thi u 3 con
(define son3 cadddr)
v.v
Ch ng h n xây d ng cây cú pháp cho bi u th c Scheme
(define L (list ’ann ’tom ’bob))
D i đây là th t c tính đ o hàm c a m t bi u th c Cây t ng quát bi u di n bi u
th c có quy c nh sau : các lá g m s nguyên và ký hi u bi u di n các bi n hình th c, các
nút trong là các phép toán Trong ví d này, đ đ n gi n, ch xét phép c ng và phép nhân
; type Varable = Symbol
; type Operator = {+, *}
; type Exp = Tree(Integer ∪ Variable ∪ Operator)
; Chú ý : ki u Exp có th mô t c th h n nh sau :
; type Exp = Integer ∪ Variable ∪ Operator × Exp × Exp
; derivative : Exp × Variable → Exp
Trang 30(create2 ’+ (create2 ’* (derivative (son1 E) V)
(son2 E)) (create2 ’* (son1 E)
(derivative (son2 E) V)))) (else
(error ”unknown operator” (root E))))) (derivative ’(+ x (* 2 y)) ’y)
4 Vi t hàm (converse P N) chuy n đ i s th p phân N b t k sang s h c s P, v i
P ≤ 36 (s trong h c s P đ c vi t b i P ch s 0 9A Z) theo g i ý nh sau :