Một cây tứ phân điểm giống nhƣ cây 2-d, đƣợc sử dụng để biểu diễn các điểm dữ liệu trong không gian hai chiều. Có điều không giống nhƣ cây 2-d là cây tứ phân điểm luôn chia một vùng thành 4 phần. Trong cây 2-d, nút N phân một vùng thành hai phần do vẽ một đƣờng thẳng đi qua điểm (N.XVAL, N.YVAL). Đƣờng kẻ này có thể là đƣờng nằm ngang nếu cấp của N là lẻ hoặc là đƣờng thẳng đứng trong trƣờng hợp cấp của N là chẵn. Đối với cây tứ phân điểm thì nút N phân một vùng mà nó biểu diễn do vẽ cả đƣờng thẳng đứng và đƣờng nằm ngang qua điểm (N.XVAL, N.YVAL). Bốn phần đƣợc tạo ra đƣợc gọi là các góc NW (Tây Bắc), SW (Tây Nam), NE (Đông Bắc) và SE (Đông Nam) xác định bởi nút N và mỗi góc tƣơng ứng với một con của nút N. Do đó các nút trong cây bốn nhánh có thể xác định 4 cành. Trƣớc khi thực hiện các thao tác đối với cây bốn cành định nghĩa đơn giản của cấu trúc nút cho một nút của cây tứ phân đƣợc đƣa ra nhƣ sau:
qtnodetype = record INFO: infotype; XVAL: real; YVAL: real;
NW, SW, NE, SE; qtnodetype; end
2.3.1 Chèn / tìm kiếm trong cây tứ phân điểm
Thực hiện khảo sát tập 5 điểm (Banja Luka, Derventa, Teslic, Tuzla và Sinj)
đã đƣợc thể hiện với cây 2-d, nó sẽ đƣợc thể hiện nhƣ thế nào thông qua một cây tứ phân. Hình 2.7 thể hiện việc chèn từng điểm vào cây, có hình 2.8 cho thấy cây tứ phân đƣợc xây dựng nhƣ thế nào.
Tiến trình này đƣợc mô tả nhƣ sau:
1. Khởi đầu cây tứ phân là rỗng, việc chèn Banja Luka tạo ra nút gốc của cây đƣợc gán nhãn với cặp (19, 45).
2. Việc chèn Derventa tạo ra vùng miêu tả bởi Banja Luka đƣợc phân thành 4 phần thông qua việc vẽ một đƣờng thẳng nằm ngang và một đƣờng thẳng đứng qua (19, 45). Derventa, ở vị trí (40, 50), nằm trong góc phần tƣ NE, do vậy Banja Luka
có con NE là Derventa.
e) Hình 2.7
Hình 2.8
3. Việc chèn Teslic đƣợc tiến hành nhƣ sau: Teslic nằm theo hƣớng Đông Nam (SE) của Banja Luka. Do vùng này hiện tại chƣa có điểm nào nên Teslic đƣợc đặt làm con SE của Banja Luka.
4. Việc chèn thêm Tuzla phức tạp hơn. Nhận thấy rằng Tuzla nằm ở SE của
Banja Luka. Do vậy, thực hiện chuyển đến nhánh SE của Banja Luka. Kết quả là góc phần tƣ SE đƣợc chia bởi vẽ đƣờng nằm ngang và đƣờng thẳng đứng qua điểm
Teslic. Với kết quả bốn phần đƣợc tạo ra, Tuzla ở góc SE và nhƣ vậy Tuzla trở thành nút con SE của Teslic.
5. Cuối cùng, việc chèn Sinj là không quá phức tạp bởi vì nó nằm ở SW của
Banja Luka. Do hiện tại con trỏ này là rỗng vậy nên đặt nút này chứa thông tin liên quan đến Sinj.
Nhìn chung chiều cao của một cây tứ phân chứa n nút có thể có giá trị lớn nhất là n-1, điều đó có nghĩa là thời gian để tìm kiếm hay chèn là nhỏ hơn số lƣợng nút. [6,17]
2.3.2 Thao tác xoá cây tứ phân điểm
Khi xóa nút N từ cây tứ phân có gốc T cũng có những nét giống nhƣ khi thực hiện với cây 2-d để tìm một nút thay thế thích hợp cho các nút không phải là lá. Đối với trƣờng hợp các nút lá thì việc xoá không có vấn đề gì: Đặt trƣờng liên kết tƣơng ứng của nút cha của N trỏ tới NIL và giải phóng không gian lƣu trữ.
Việc xoá trong cây tứ phân là rất phức tạp. Hình 2.9 chỉ ra tại sao lại phức tạp. Đầu tiên mỗi nút trong cây tứ phân thể hiện trong một vùng và vùng này đƣợc định nghĩa hơi khác so với cây 2-d. Đối với cây 2-d nó đủ để kết hợp 4 ràng buộc dƣới dạng xc1, x<c2, yc3, y<c4 với các hằng số c1,….,c4. Do đó nhƣ trong trƣờng hợp
cây 2-d khi mở rộng nodetype thành cấu trúc mới newnodetype, trong trƣờng hợp này cũng có thể mở rộng cấu trúc nút qtnodetype thành một cấu trúc mới
newnodetype,với cùng với kiểu trƣờng trên đây (XLB,YLB,XUB,YUB).
newqtnodetype = record INFO: infotype; XVAL, YVAL: real;
XLB, YLB, XUB, YUB: real {-, +}; NW, SW, NE, SE: newqtnodetype
end
Khi chèn nút N vào cây T phải đảm bảo những điểm dƣới đây:
Nếu N là gốc của cây T, thì N.XLB=-, N.YLB=-, N.XUB=+, và N.YUB=+.
2. Nếu P là cha của N thì khi đó bảng 2.2 dƣới đây mô tả những giá trị của các trƣờng XLB, YLB, XUB, YUB của N tuỳ thuộc vào việc N là con NW, SW, NE hay SE của P, trong đó sử dụng ký hiệu w=(P.XUB-P.XLB) và h=(P.YUB-P.YLB).
Trƣờng hợp N.XLB N.XUB N.YLB N.YUB
N= P.NW P.XLB P.XLB + w x 0.5 P.YLB + h x 0.5 P.YUB
N=P.SW P.XLB P.XLB + w x 0.5 P.YLB P.YLB + h x 0.5
N=P.NE P.XLB + w x 0.5 P.XUB P.YLB + h x 0.5 P.YUB
N=P.SE P.XLB + w x 0.5 P.XUB P.YLB P.YLB + h x 0.5
Bảng 2.2
Để vận dụng thành công kỹ thuật xoá trong với cây tứ phân điểm thì khi xoá một nút trong N phải tìm một nút thay thế R từ một trong các cây con của N ( từ một trong N.NW, N.SW, N.NE, N.SE) sao cho mỗi nút R1 trong N.NW là ở phía tây bắc của R, và mỗi nút R2 trong N.SW ở phía tây nam R, mỗi nút R3 trong N.NE ở phía đông bắc của R và mỗi nút R4 trong N.SE ở phía đông nam của R.
Hãy xem xét cây tứ phân trên hình 2.8 và hình 2.9. Giả sử, muốn xoá Banja Luka từ cây tứ phân này. Trong trƣờng hợp này, nút thay thế thực tế đƣợc tìm là
Teslic. Không nút nào khác thoả mãn những điều kiện đã đặt ra ở trên. Tuy nhiên, không phải luôn có khả năng tìm đƣợc một nút thay thế. Do vậy trong trƣờng hợp
xấu nhất việc xoá một nút N có thể yêu cầu việc chèn lại một số nút trong cây con trỏ bởi N.NE, N.SE, N.NW và N.SW.[17]
2.3.3 Truy vấn khoảng trong cây tứ phân điểm
Các truy vấn khoảng trong cây tứ phân đƣợc thực hiện gần nhƣ cách thức thực hiện trong cây 2-d. Mỗi nút trong một cây tứ phân thể hiện một vùng và phƣơng pháp tính toán và truy vấn khoảng tránh việc tìm kiếm các cành bắt nguồn từ những nút mà các vùng lên quan đến chúng không giao với đƣờng tròn định nghĩa bởi truy vấn khoảng. Giả thiết rằng, cần phải tìm kiếm cây tứ phân điểm bắt nguồn từ T với tất cả các điểm trong một đƣờng tròn C, tâm (xc, yc) và có bán kính là r, giải thuật đƣợc nêu ra nhƣ sau:[6,17]
Giải thuật 2.1
Proc RangeQueryPointQuadtrees(T: newqtnodetype, C: cirle) 1.If region(T) C = then Halt
2. else
(a) If (T.XVAL, T.YVAL)C then print (T.XVAL, T.YVAL); (b) RangeQueryPointQuadtree(T.NW,C);
(c) RangeQueryPointQuadtree(T.SW,C); (d) RangeQueryPointQuadtree(T.NE,C); (e) RangeQueryPointQuadtree(T.SE,C); End proc
2.4 Cây tứ phân matrix MX (MX-Quadtrees)
Trong cả hai trƣờng hợp cây 2-d và cây tứ phân điểm, hình thù của cây phụ thuộc vào thứ tự các đối tƣợng đƣợc chèn vào cây. Đặc biệt, thứ tự ảnh hƣởng đến chiều cao của cây, do đó ảnh hƣởng đến độ phức tạp của các thao tác tìm kiếm và chèn. Mỗi nút N của cây 2-d và cây tứ phân điểm biểu diễn vùng và phân chia vùng thành 2 (trƣờng hợp cây 2-d) hoặc 4 (trƣờng hợp cây tứ phân) vùng con. Việc phân chia có thể không đều vì nó phụ thuộc vào vị trí điểm (N.XVAL, N.YVAL) trong vùng biểu diễn bởi N.
Ngƣợc lại, mục tiêu của cây MX-quadtree là để đảm bảo hình dạng ( và chiều cao) của cây độc lập với số lƣợng các nút của cây, cũng nhƣ thứ tự chèn các nút này. Thêm nữa, MX-quadtree tập trung vào việc đem lại các giải thuật xoá và tìm kiếm có hiệu quả.
Một cách ngắn gọn, cây MX-quatree làm việc nhƣ sau: Đầu tiên, giả định rằng bản đồ đang đƣợc phân thành một lƣới kích thƣớc (2k x 2k). Ngƣời phát triển ứng dụng tự do lựa chọn k và một khi nó đƣợc chọn thì nó phải cố định.
MX-quadtree có cấu trúc nút tƣơng tự nhƣ cây tứ phân điểm, đó là chúng có kiểu newqtnodetype. Có một sự khác biệt là gốc của MX-quadtree miêu tả vùng xác định bởi XLB = 0, XUB = 2k, YLB = 0, YUB = 2k. Hơn nữa, khi một vùng đƣợc phân chia, nó đƣợc chia ở giữa. Do vậy, nếu N là một nút, khi đó các vùng thể hiện bởi bốn cành của N đƣợc mô tả theo bảng 2.3 dƣới đây. Trong bảng này, w ký hiệu chiều rộng của vùng đƣợc biểu diễn bởi N và đƣợc cho bởi w = N.XUB – N.XLB.
Do tất cả các vùng đƣợc biểu diễn bởi các nút trong MX-quadtree là các vùng vuông, nên w = N.YUB – N.YLB.[4,6]
Con XLB XUB YLB YUB
NW N.XLB N.XLB + w/2 N.YLB + w/2 N.YLB + w
SW N.XLB N.XLB + w/2 N.YLB N.YLB + w/2
NE N.XLB + w/2 N.XLB + w N.YLB + w/2 N.YLB + w
SE N.XLB + w/2 N.XLB + w N.YLB N.YLB + w/2
Bảng 2.3
2.4.1 Chèn và tìm kiếm trong MX-Quadtree
Xem xét cách chèn điểm vào cây MX-Quadtree nhận thấy, mỗi điểm (x,y) trong cây MX-Quadtree biểu diễn vùng 1x1 mà góc dƣới bên trái là (x,y). Điểm chèn vào nút biểu diễn vùng 1x1 tƣơng ứng với điểm này. Giả sử, phải chèn thêm các điểm A, B, C và D nhƣ trên hình 2.12, các bƣớc thực hiện sẽ đƣợc tiến hành nhƣ dƣới đây:
1. Việc chèn điểm A với toạ độ (1,3) nhƣ sau: Là nút gốc biểu diễn toàn bộ vùng và A nằm trong NW. Do vậy, cành NW của gốc tƣơng ứng vùng 2x2 mà góc dƣới bên trái của nó là điểm (0, 2). Điểm A nằm trong góc NE của vùng này. Hình 2.12a chỉ ra kết quả cây tứ phân NX sau khi chèn điểm A. Hình 2.13 chỉ ra việc phân chia vùng. Chú ý rằng điểm A đƣợc chèn vào mức 2 của cây và mức này bằng giá trị k. Tổng quát là điểm luôn đƣợc chèn vào mức k trong cây tứ phân MX.
2. Việc chèn điểm B với toạ độ (3, 3) sẽ xác định đƣợc B thuộc nhánh NE của gốc. Do vậy cành NE của nút gốc tƣơng ứng vùng 2x2 với góc dƣới bên trái là (2, 2). Điểm B lại nằm trong góc NE của vùng này. Kết quả đƣợc thể hiện trên hình 2.12b và 2.13b.
3. Việc chèn điểm C với toạ độ (3, 1) đƣợc tiến hành nhƣ sau; C nằm trong góc SE của toàn vùng. Điều này đòi hỏi tạo nút con SE của gốc. C nằm trong vùng con NE của nút này. Hình 2.12c và 2.13c chỉ ra kết quả.
4. Cuối cùng, hình 2.12d và 2.1d biểu diễn kết quả sau khi chèn D.
2.4.2 Thao tác xoá trong MX-Quadtrees
Thao tác xoá trong một MX-Quadtrees là một thao tác tƣơng đối đơn giản bởi vì toàn bộ các điểm đều nằm ở cấp cuối ( đều là các nút lá). Lƣu ý rằng nếu N là một nút không phải lá trong cây MX-Quadtrees với gốc là T thì khi đó vùng biểu diễn bởi nút N có ít nhất một điểm thuộc cây. Nếu muốn xoá một điểm (x, y) từ cây T, việc đầu tiên là thiết lập liên kết tƣơng ứng của cha nút N tới NIL. Nói cách khác nếu M là cha của N và M.DIR trỏ tới N thì thiết lập M.DIR=NIL và cho lại N để giải phóng vùng nhớ. Bây giờ tiến hành kiểm tra xem bốn trƣờng liên kết của M đều là NIL? Nếu đúng, khảo sát cha của M ( gọi là P). Vì M là con của P, tìm đƣờng liên kết DIR1 sao cho P.DIR1=M. Sau đó thiết lập P.DIR1=NIL và tiếp tục kiểm tra xem toàn bộ các trƣờng liên kết của P có là NIL? Nếu đúng tiếp tục tiến trình. Toàn bộ tiến trình đòi hỏi phải duyệt qua cây một lần từ đỉnh xuống đáy (để tìm nút sẽ xoá) và một lần đi ngƣợc cây. Nhƣ vậy toàn bộ tiến trình là O(k) lần.
Hãy xem xét tiến trình làm việc ra sao với cây MX trên hình 2.12d. Giả sử, yêu cầu phải xoá D. Việc xoá nút D không khó khăn vì có thể tìm ra D và đặt NIL
vào trƣờng liên kết SE của cha nó (cái trỏ đến D). Để xác định xem cha của D có hỏng? Kiểm tra xem bốn trƣờng liên kết nó là NIL? Không đúng vậy vì C và D có cùng cha.
Mặt khác, xem xét việc huỷ bỏ A từ cây tứ phân MX trong hình 2.12d. Khi đặt NIL vào trƣờng NE của cha nút A, nhận thấy rằng cha của A kết thúc bởi 4 trƣờng rỗng. Nhƣ vậy cha của A bị hỏng. Khi điều đó xảy ra, khảo sát cha của A (là gốc) và đặt NIL vào liên kết NW của gốc. Khi kiểm tra xem có toàn bộ bốn trƣờng liên kết là NIL? Điều đó không xảy ra và dẫn tới không thể bị phá vỡ.
2.4.3 Truy vấn khoảng trong MX-Quadtrees
Các truy vấn khoảng trong MX-Quadtrees đƣợc thực hiện một cách hoàn toàn tƣơng tự nhƣ cây tứ phân điểm. Chỉ có hai điểm khác biệt là: Nội dung của các trƣởng XLB, XUB, YLB và YUB là khác nhau. Điểm khác biệt thứ hai là trong cây
MX-Quadtrees tất cả các điểm nằm ở các nút lá, do vậy đƣờng tròn định nghĩa bởi truy vấn khoảng cần đƣợc thực hiện chỉ cấp độ lá.
2.4.4 PR-Quadtrees
PR-Quadtrees là một sự biến thể của MX-Quadtrees, trong MX-Quadtrees tất cả các điểm đƣợc lƣu lại tại các nút lá. Vì thế khi xem xét một MX-Quadtrees biểu diễn vùng 2k x 2 k, việc tìm kiếm và chèn là quy trình O(k).
Nhớ lại rằng mỗi nút N trong cây MX biểu diễn một vùng, Reg(N). Bằng cách mở rộng cấu trúc dữ liệu để bao gồm điểm trong nó, ta có thể điều chỉnh luật chia vùng cho cây tứ phân MX bằng cách đòi hỏi nút N bị chia nếu Reg(N) chứa hai hay nhiều điểm. Nếu N chứa 1 điểm thì nó đƣợc lƣu trong nút N thay cho nút lá. Điều này tránh đƣợc việc mở rộng nút N và làm giảm thời gian chèn và tìm kiếm.[6]
2.5 Cây R (R-Trees)
Cây R (R-Trees) là kiểu cấu trúc dữ liệu mới, cấu trúc này có thể đƣợc sử dụng để lƣu trữ các vùng chữ nhật của một hình ảnh hay bản đồ. R-Trees đặc biệt hữu ích trong việc lƣu trữ dữ liệu số lƣợng lớn trên đĩa. Do việc truy cập đĩa thƣờng rất chậm, R-trees cung cấp một cách thuận tiện trong việc cực tiểu hoá số lần truy cập đĩa.
Mỗi R-Trees kết hợp với một thứ tự là một số nguyên K. Mỗi nút R-Trees
không phải là lá bao gồm một tập từ K/2 đến K hình chữ nhật. Bằng trực quan thấy rằng mỗi nút không lá trong R-Trees trừ gốc ít nhất phải là một nửa. Đặc điểm này làm cho R-Trees thích hợp với việc truy vấn đĩa với vì mỗi truy cập đĩa mang lại một trang chứa đựng trong một trang, chiều cao của R-Trees sử dụng để lƣu trữ tập hợp các hình chữ nhật, thƣờng rất nhỏ. Do vậy số lần truy cập đĩa giảm bớt so với các cây mô tả trên.
Một hình chữ nhật hoặc là “thực” hoặc là một hình bao hàm một nhóm hình chữ nhật. Các nút lá bao gồm một hình chữ nhật “thực” trong khi các nút không lá bao gồm các hình chữ nhật nhóm từ một tập các hình chữ nhật. Hình 2.14 chỉ ra cách nhóm các hình chữ nhật nhƣ sau. Nhóm Các chữ nhật G1 R1, R2, R3 G2 R4, R5, R6, R7 G3 R8, R9 Bảng 2.4
Hình 2.14 chỉ ra cây R bậc 4 liên kết với các chữ nhật trên hình 2.14. Bảng 2.4 là kết quả có đƣợc. Cấu trúc của một R-Trees đƣợc định nghĩa nhƣ sau:
rtnodetype = record
Rectl,…, Rectk: Rectangle; P1,…, Pk: rtnodetype; end
Kiểu dữ liệu Rectangle sẽ không đƣợc đề cập ở đây, thực tế có rất nhiều cách để biểu diễn chữ nhật.[17]
2.5.1 Chèn và tìm kiếm trong R-Trees
Khi chèn một hình chữ nhật mới vào một R-Trees thực hiện theo những bƣớc dƣới đây:
1. Xem xét trong số các hình chữ nhật liên quan với nút gốc hình nào cần đƣợc mở rộng ít nhất (về mặt diện tích) để chứa hình chữ nhật đƣợc chèn. Ví dụ nếu chèn hình chữ nhật R10 (hình 2.16) vào cây R trên hình 2.15 thì cách dễ nhất là mở rộng nhóm G1 bởi vì việc mở rộng các nhóm khác thì diện tích bị bao phủ bởi nhóm này sẽ tăng đáng kể.
2. Do đó từ những liên kết của G1 (từ gốc, hình 2.15) dẫn tới chèn R10 vào khe có sẵn.
3. Tiếp theo, xem xét việc chèn R11. Nhóm mà diện tích của nó phải đƣợc mở rộng tối thiểu trong trƣờng hợp này là G2. Tuy nhiên, con G2 của gốc đã đầy. Do