Tải bản đầy đủ (.doc) (9 trang)

Thực thi các phương pháp ADT từ điển có sắp thứ tự dùng một cây AVL

Bạn đang xem bản rút gọn của tài liệu. Xem và tải ngay bản đầy đủ của tài liệu tại đây (150.95 KB, 9 trang )

Báo cáo tổng hợp đồ án môn học Lập trình hớng đối tợng

Lời nói đầu
Ngày nay sự phát triển của ngành tin học đã đóng một vai trò to lớn
trong đời sống của con ngời. Tin học đợc ứng dụng rộng rãi trong nhiều
ngành, nhiều lĩnh vực và hiệu quả của nó rất cao, giải quyết nhiều công
việc mà tởng chừng con ngời rất khó thực hiện.
Tuy nhiên hệ thống tin học ngày càng phức tạp, vì vậy xu thế áp
dụng phơng pháp thiết kế hớng đối tợng ngày càng đợc sử dụng rộng rãi
thay cho phơng pháp cấu trúc (là phơng pháp truyền thống) và ngày càng
đợc phổ biến khi xây dựng phần mềm lớn và phức tạp.
Vì vậy môn học Lập trình hớng đối tợng là một môn học đợc dạy ở
hầu hết các khoa Công nghệ thông tin ở các trờng Đại học.
Với mục tiêu trang bị cho sinh viên khoa Công nghệ thông tin một
kiến thức cơ sở về lập trình hớng đối tợng, làm nền móng để phát triển
sau này. Với các kiến thức đã học, các tài liệu tham khảo, dới sự trực tiếp
giảng dạy và hớng dẫn của thầy Huỳnh Quyết Thắng, chúng tôi đã tìm
hiểu và xây dựng bài toán Thực thi các phơng pháp ADT từ điển có sắp
thứ tự dùng một cây AVL.
Vì trình độ cũng nh thời gian có hạn nên không tránh khỏi những
khuyết điểm, không đầy đủ , và thiếu sót, rất mong các bạn đóng góp ý
kiến.
Cuối cùng chúng tôi xin chân thành cám ơn sự hớng dẫn nhiệt tình
của thầy Huỳnh Quyết Thắng - Bộ môn Công nghệ phần mềm, đã chỉ dẫn
tận tình và giúp đỡ chúng tôi hoàn thành bài tập này !

Đối với một bài toán đợc đa ra , chúng ta có các cách khác nhau
để giải quyết cùng bài toán, sao cho có thể khảo sát, sử dụng những hiệu
năng khác nhau.
Trong báo cáo này chúng ta sẽ giải thích các cách khảo sát khác
nhau để giải quyết bài toán thực thi một từ điển có sắp thứ tự. Tức là ta sẽ



1


Báo cáo tổng hợp đồ án môn học Lập trình hớng đối tợng

ngnhiên cứu vài cấu trúc dữ liệu dựa trên các cây khác nhau để thể hiện
các từ điển có sắp thứ tự.
Thao tác tìm kiếm trên cây nhị phân tìm kiếm là 1 thao tác quan
trọng, nó làm cơ sở, nền móng cho các thao tác khác. Thao tác này dựa
trên thủ tục TreeSearch(k,v) trong đó k: khóa tìm kiếm ; v: nút trong của
cây nhị phân tìm kiếm; kết quả trả về là một nút w của cây T(v).
TreeSearch (int k,CBTNode *v)
{
if (isExternal(v))
return v;
if (k== v->keys())
return v;
else
if (k<v->keys())
return TreeSearch(k,v->getLeft());
else
return TreeSearch(k,v->getRight());
}
Cũng nh vậy, trong các thao tác cập nhật trên cây nhị phân tìmkiếm
với 2 thao tác cơ bản là Chèn(insertitem(k,e)) và Gỡ
bỏ(removeElement(k)) trên một từ điển D đợc thực thi với một cây nhị
phân tìm kiếm.
Với phép chèn: ta bắt đầu bằng bằng cách gọi thủ tục
TreeSearch(k,T.root())

trên T và các phép xử lý tiếp theo đối với kết quả trả về. Vì số lợng các
nút đã thăm tỷ lệ với chiều cao h của T trong trong trờng hợp xấu nhất
cho nên thao tác này thực hiện với thời gian O(h)
Với phép gỡ bỏ: ta cũng phải bắt đầu với thủ tục
TreeSearch(k,T.root()) và các phép xử lý tiếp theo đối với kết quả trả về
(Kết thúc nếu không tìm thấy nút nào có khóa k hoặc các phép gỡ bỏ và
cấu trúc lại). Thuật toán gỡ bỏ cũng tơng tự nh các thuật toán chèn và tìm

2


Báo cáo tổng hợp đồ án môn học Lập trình hớng đối tợng

kiếm. Ta bỏ ra O(1) thời gian tại mỗi nút đã thăm và trong trờng hợp xấu
nhất , số lợng các nút đã thăm tỷ lệ với chiều cao h của T vì vậy thao tác
removeElement(k) cũng chạy trong thời gian O(h).
Khả năng vận hành:
Phép toán
Thời gian
Size , isEmpty
O(1)
FindElement, insertitem,remove Element O(h)
FindAllElements, remove AllElements
O(h+s)
Để mô tả một lớp cây nhị phân tìm kiếm ta xây dựng một lớp
BinarySearchTree, lớp này lu trữ các cặp khóa - thành phần của lớp
item(lu trữ các vị trí (các nút) của cây nhị phân cơ sở của nó).
Lớp BinarySearchTree độc lập với cách thực thi cụ thể của cây nhị
phân và nó vận dụng khả năng dùng lại mã của nó.
CBinaryTree

root

CItem

roots()
setRoot()
isInternal()
isExternal()
insertItem()
removeElement()
TreeSearch()

key
elem
keys()
elements()
setKey()
setElement()

Mô hình cây nhị phân mang lại khá nhiều điểm lý thú , tuy nhiên khả
năng vận hành trong trờng hợp xấu nhất mà nó đạt đợc cho nhiều phép
toán khác nhau là theo thời gian tuyến tính và nó cũng không tốt hơn khả
năng vận hành của các thực thi từ điển gốc. Khắc phục vấn đề này (để đạt
đợc thời gian loga cho tất cả các phép toán từ điển căn bản) bằng cách bổ
sung một quy tắc vào phần định nghĩa cây nhị phân tìm kiếm; đó là tính
chất chiều cao cân đối.
Tính chất chiều cao cân đối: Với mọi nút trong của T, chiều cao
của các con của v có thể khác nhau tối đa là 1.

3



Báo cáo tổng hợp đồ án môn học Lập trình hớng đối tợng

H.9.9(a)
H.9.9(b)
9.9.a: Hình sau khi thêm nút có khoá 54 thì các nút có khoá (78 và 44)
trở nên không cân bằng
9.9.b: Hình sau khi 3 nút đợc cấu trúc( sắp xếp) lại .
Các phép toán chèn và gỡ bỏ của các cây AVL cũng tơng tự nh trờng hợp cây nhị phân tìm kiếm; song chúng ta phải thực hiện các phép
toán bổ sung để đảm bảo tính chất của cây AVL. Và nh vậy chúng ta sẽ
phải bổ xung thêm thủ tục Restructure(x) - là phơng pháp cấu trúc lại 3
nút; thời gian chạy cho các trờng hợp này luôn đạt đợc thời gian loga.
Khả năng vận hành:
Phép toán
Thời gian
Size , isEmpty
O(1)
FindElement, insertitem,remove Element O(logn)
FindAllElements, remove AllElements
O(logn+s)
Để mô tả cho cây AVL chúng ta xây dựng lớp AVLitem - là mở
rộng lớp item; còn lớp AVLTree là mở rộng lớp BinarySearchTree
CAVLTree
reStructure_a()
reStructure_b()
reStructure_c()
reStructure_d()
reStructure()
tallerChild()

setHeightTree()

CAVLItem
height
getHeight()
setHeight()

4


Báo cáo tổng hợp đồ án môn học Lập trình hớng đối tợng

Trong một vài cấu trúc dữ liệu mà ta thờng gặp là các cây đa hớng(các cây có các mắt trong có 2 con trở lên) nh vậy rõ ràng khả năng lu
trữ của nó sẽ tăng lên rõ rệt. Tuy nhiên ta sẽ không đề cập đến các thao
tác cập nhật trên các cây tìm kiếm đa hớng. Việc tìm kiếm trên cây đa hớng khá đơn giản: ta thực hiện 1 lần tìm kiếm nh vậy bằng cách vẽ 1 lộ
trình trong T bắt đầu từ gốc. Khi ở tại một nút v-d(là nút có d khóa ) ta so
sánh k với các khóa k1, k2,....., kd-1 đợc lu trữ tại v; nếu k = ki nào đó thì
đợt tìm kiếm kết thúc thành công. Bằng không ta tiếp tục tìm kiếm nh
vậy; nếu đạt đến nút ngoài mà khôn có nút nào có khóa bằng k thì đợt tìm
kiếm kết thúc không thành công.

A

B

C

5



Báo cáo tổng hợp đồ án môn học Lập trình hớng đối tợng

Hỡnh 9.3: (A) Mt cõy tỡm kim a ng; (B) Tỡm ng i trong
T cho khoỏ 12 (khụng thnh cụng); (C) Tỡm ng i trong T cho khoỏ
24 (thnh cụng)
Trờng hợp đặc biệt của cây đa hớng là cây (2,4); cây (2,4) có đặc
điểm duy trì cây đa hớng ở trạng thái cân bằng. Muốn vậy nó luôn phải
duy trì hai tính chất đơn giản sau:
Tính chất kích cỡ: mọi mắt đều có tối đa 4 mắt con
Tính chất chiều sâu: tất cả các mắt ngoài đều có cùng chiều sâu
Các thao tác cập nhật trên cây tìm (2,4) cũng đợc thực hiện với
việc bắt đầu bằng việc tìm kiếm khóa k (nh việc tìm kiếm trên cây tìm đa
hớng).
Khả năng vận hành:
Phép toán
Thời gian
Size , isEmpty
O(1)
FindElement, insertitem,remove Element O(logn)
FindAllElements, remove AllElements
O(logn+s)
Đối với phơng pháp chèn của chúng ta bảo đảm tính chất chiều sâu;
nhng nó có thể vi phạm tính chất kích cỡ và kiểu vi phạm này đợc gọi là
một sự cố tràn tại nút v; để sửa sự cố tràn này chúng ta thực hiện một
phép tách(split) trên v. Chúng ta có thể dễ dàng nhận thấy rằng tổng thời
gian để thực hiện một phép chèn trên cây (2,4) luôn mất một thời gian là
O(logn).
Phép gỡ bỏ cũng bảo đảm tính chất chiều sâu; nhng nó cũng có thể
vi phạm tính chất kích cỡ tại v.
Mặc dù cây AVL và cây (2,4) có một số thuộc tính tốt nhng vẫn có

những ứng dụng từ điển mà chúng không phù hợp lắm. Ví dụ, cây AVL
yêu cầu nhiều thao tác xây dựng lại cây mỗi khi có một phần tử đợc loại
bỏ; còn cây AVL yêu cầu nhiều thao tác hợp nhất hoặc loại bỏ. Còn trúc
dữ liệu mà chúng ta xét trong chơng này, cây đỏ đen, không có những hạn
chế đó, tuy nhiên nó yêu cầu chỉ những thay đổi có cấu trúc O(1) đợc
phép tạo ra sau mỗi lần cập nhật để duy trì cân bằng. Một cây đỏ đen là

6


Báo cáo tổng hợp đồ án môn học Lập trình hớng đối tợng

một cây nhị phân nhị phân tìm kiếm mà mỗi nút của nó đợc tô màu đỏ
hoặc đen theo cách nh sau :
Gốc màu đen
Mọi nút ngoài đều màu đen
Các con của một nút đỏ là đen
Các nút ngoài có một độ sâu đen nh nhau, đợc định nghĩa là số
các tổ tiên đen trừ đi một
Mô tả lớp cây đỏ đen:
CRBTree
insertItem()
removeElement()
reStructureRB_a()
reStructureRB_b()
reStructureRB_c()
reStructureRB_d()
reStructureRB()
reStructureRBTree()
reStructure1()

reStructure2()
reStructure3()

Xem xét việc chèn một phần tử x với khoá k trên 1 cây đỏ đen T,
chúng ta sử dụng sự tơng ứng giữa T và cây (2,4) T và thuật toán chèn
cho cây T. Thuật toán chèn đầu tiên thao tác nh trên một cây nhị phân
tìm kiếm. Đó là, tìm k trong T cho tới khi gặp nút ngoài của T, thay thế
nút này bằng một nút trong z, lu trữ (k,x) và có 2 nút con ngoài. Nếu z là
gốc của T, ta tô màu đen cho z, các trờng hợp khác tô màu đỏ. Chúng ta
cũng tô màu các con của z màu đen. Thao tác này tơng ứng với việc chèn
(k.x) vào một nút của cây (2,4) T với các con ngoài. Thêm vào đó hành
động này bảo toàn các thuộc tính gốc, lá và độ sâu của T nhng nó có thể
vi phạm thuộc tính trong. Thực sự là nếu z không phải là gốc của T và cha
v của z là đỏ thì chúng ta có một cha và một con (đó là v và z) cùng màu
đỏ. Chú ý rằng theo thuộc tính gốc, v không thể là gốc của Tvà theo thuộc
tính trong (đã đợc thoả mãn trớc đó ) cha u cua v phải là đen. Vì z và cha

7


Báo cáo tổng hợp đồ án môn học Lập trình hớng đối tợng

của nó là đỏ nhng ông của z là u lại là đen nên chúng ta gọi sự vi phạm
thuộc tính trong này là đỏ kép tại nút z.
Cũng nh khi loại bỏ 1 phần tử ra khỏi cây thì có thể xuất hiện tình trạng
đen kép
Trong tất cả các trờng hợp nh vậy thì chúng ta đều phải sử dụng thủ tục
reStructure() để xây dựng lại.
Từ các phân tích trên chúng ta xây dựng các lớp và sơ đồ kế thừa nh sau:


(trang sau)

8


B¸o c¸o tæng hîp ®å ¸n m«n häc LËp tr×nh híng ®èi tîng

CItem
key
elem
keys()
elements()
setKey()
setElement()

CAVLTree
reStructure_a()
reStructure_b()
reStructure_c()
reStructure_d()
reStructure()
tallerChild()
setHeightTree()

CBTNode
left
right
parent
sibling


CAVLItem
height

getLeft()
getRight()
getParent()
getSibling()
setLeft()
setRight()
setParent()
setSibling()
isBalanced()
isDoubleRed()
isDoubleBlack()
maxHeight()
setHeightNode()

getHeight()
setHeight()

CBinaryTree
root
roots()
setRoot()
isInternal()
isExternal()
insertItem()
removeElement()
TreeSearch()


9

CRBTree
insertItem()
removeElement()
reStructureRB_a()
reStructureRB_b()
reStructureRB_c()
reStructureRB_d()
reStructureRB()
reStructureRBTree()
reStructure1()
reStructure2()
reStructure3()



×