các bạn có thể tham khảo các bài khác ở đây: cơ sở dữ liệu và giải thuật

cấu trúc phi tuyến mà chúng ta xét ở đây là cấu trúc cây, rất phổ biến trong đời sống.
1.định nghĩa và các khái niệm:


android.vn/attachments/untitled-copy-png.116991/" border="0" alt="" />

khái niệm: cây là tập hợp của một số hữu hạn các nút mà có một nút đặc biệt gọi là gốc( root) các nút có quan hệ phân cấp gọi là "cha-con".
ta có thể thấy:
  • một nút cũng là một cây và là gốc của cây đấy.
  • t1,t2,t3...ti là các cây với r1,r2,r3...ri là các gôc tương ứng. r là một nút và r có quan hệ cha con với các nut(gốc) r1,r2,,r3...ri thì một cây mới t được tao thành với gốc là r, các cây t1,t2,t3...ti là các cây con của t (substrees)
  • một cây không có nút nào thì gọi là một cây rỗng.
- số các con của một nút là cấp(degree) của nút đó:





như trên hình ta thấy, cấp của j là 2, cấp của b là 3 cấp của z là 2
- nút có cấp bằng 0 được gọi là lá (leaf) như trên hình hoặc là nút tận cùng (terminal node) nút không là lá được gọi là nút nhánh.
- cấp cao nhất của nút cũng là cấp của cây đó. ví dụ cây trên cấp cao nhất là 3
- gốc của cả cây đó có level là 1, level của một nút là i thì nút con của nó có level i+1 vd: j có level là 1






- chiều cao hay chiều sâu của một cây là số mức lớn nhất có trên cây đó.
- nếu n1,n2...nk có quan hệ cha con: ni là cha ni+1 thì dãy đó là đường đi từ n1 đến nk, độ dài của đường đi bằng số nút trên đường đi trừ 1.
- cấu trúc cây không tồn tại chu trình, tổ chức cấu trúc cây giúp ta tru cập nhanh vào các phần tử của nó.

2.cây nhị phân(binary tree):
-cây nhị phân lafc cây mà mỗi nút chỉ gồm tối đa là 2 nút con, đối với cây con của một nút, ta phân biệt ra là cây con trái và cây con phải.



một số dạng đặc biệt của cây nhị phân:








[img]data/attachments/116/116511-c0f9f9b5614e0c469ff7c3442fd2a240.jpg[/img]


* các tính chất của một cây nhị phân :
  • số lượng tối đa các nut ở mức i của một cây nhị phân là

    [img]data/attachments/116/116521-46f35453bdee94dc1063249681bd9aeb.jpg[/img]

    (i >=1)
  • số lượng tối đa của cây nhị phân có chiều cao h là: 2^h-1
* biểu diễn cây nhị phân:
để lưu trữ cây nhị phân trong bộ nhớ:
- lưu trữ kế tiếp: cách lưu trữ này thích hợp với cây nhị phân đầy đủ, hoàn chỉnh, nhưng nếu như những cây lệch trái cây lệch phải sẽ tạo ra sự lãng phí rất lớn, vì vậy mình sẽ không đi sâu vào phần này.
- lưu trữ móc nối: lưu trữu móc nối với một cây nhị phân sẽ rất thích hợp và nó phản ánh đc dạng tự nhiên của cây:
mỗi nút của cây nhị phân tương ứng với mooth phần tử và ta chia mỗi nút ấy ra thành 3 phần chính lf con trỏ trái, con trỏ phải và phần thông tin dữ liệu của phần tử đó giống như lưu trữ móc nối kép của danh sách đã học ở bài trước:






  • lptr con trỏ trái.
  • rptr con trỏ phải.
  • info biểu diễn thông tin





* duyệt cây nhị phân:
- có 3 cách duyệt cây nhị phân chính:

  • duyệt cây theo thứ tự trước(tức là phép xử lý gốc sẽ để lên trước)- bước 1: xử lý gốc(root)- bước 2: duyệt cây con trái theo thứ tự trước (khi xử lý cây con này thì lại gồm 3 bước lắp lại)- bước 3: duyệt cây con phải theo thứ tự trước
  • duyệt cây theo thứ tự giữa- bước 1 :duyệt cây con trái theo thứ tự giữa
    - bước 2: xử lý gốc(root)- bước 3: duyệt cây con phải theo thứ tự giữa
  • duyệt cây theo thứ tự sau.- bước 1: duyệt cây con trái theo thứ tự sau.- bước 2: duyệt cây con phải theo thứ tự sau.- bước 3: xử lý gốc(root).
- những cách duyệt trên đây là viết theo đệ quy với trường hợp suy biến là cây sẽ rỗng, khi cây rỗng thì ta không thực hiên gì cả. để giúp các bạn hiểu rõ hơn cái ý nghĩa đệ quy ở đây thì mình sẽ nói hoàn toàn bằng ngôn ngữ bình thường diễn đạt tiến trình máy thực hiện khi dùng phương pháp duyệt cây theo thứ tự trước để duyệt cây sau:




  • xử lý gốc ta được j
  • duyệt cây con trái j
  • xử lý gốc ta đc z
  • duyệt cây con bên trái của z
  • xử lý gốc ta được b
  • duyệt cây con trái b
  • xử lý gốc ta được q
  • duyệt cây con bên trai q: không có cây con bên trai q vậy là rỗng, chuyển sang duyệt cây con bên phải q: rỗng, không làm thao tác gì cả.
  • chuyển sang duyệt cây con bên phải b
  • xử lý gốc: ta được k
  • duyệt cây con bên trái k: rỗng, duyệt cây con bên phải k: rỗng.
  • chuyển sang duyệt cây con bên phải z
  • xử lý gốc ta được r
  • duyệt cây con bên trái r: rỗng, duyệt cây con bên phải r: rỗng
  • duyệt cây con bên phải j
  • xử lý gốc ta được a
  • duyệt cây con bên trái a: rỗng, không làm gì cả
  • duyệt cây con bên phải a
  • xử lý gốc ta được d
  • duyệt cây con bên trái d
  • xử lý gốc được f
  • duyệt cây con bên trái f: rỗng, cây con bên phải f: rỗng
  • duyệ cây con bên phải d
  • xử lý gốc ta được l
  • duyệt cây con bên trái l: rỗng, duyệt cây con bên phải l: rỗng
  • kết thúc sau quá trình duyệt ta có:j z b q k r a d f l
-quá trình sẽ được viết ngắn gọn như sau:
- procedure tbt(p) (p là con trỏ trỏ tới góc cây đã cho dưới dạng lưu trữ móc nối)
if p # null then
call tbt(lptr(p)) (lptr(p) chỉ cây con bên trái của p)
call tbt(rptr(p)) (rptr(p) chỉ cây con bên phải của p)
end
(cứ mỗi lần call là lời gọi lại hàm tpt )




bài hôm nay tạm thời đến đây thôi 2 phép duyệt cong lại cũng tương tự các bạn chịu khó đọc lại rồi tưởng tượng với phép duyệt giữa và sau máy sẽ chạy thế nào để duyệt được hết tất cả các phần tử trong một cây.

bài tập cho các bạn :
1. thực hiện nốt 2 phép xử lý giữa và sau.
2. cho cây:




-nút nào là nút lá
- các nút nào là nút nhánh
- cha của từng nút k,l,f,p là những nút nào
- con của nút b là nút nào
- mức của b,a
- cấp của b, z và cấp của cây là bao nhiêu
- chiều cao của cây là bao nhiêu
- đường bđi từ z đến x



có gì thắc mắc các bạn có thể liên hệ face book mình:http://www.facebook.com/linh193