5.CayPhanCap Python

You might also like

Download as pdf or txt
Download as pdf or txt
You are on page 1of 24

4/17/2022

Chương 5.
Cấu trúc cây phân cấp
TS. Hoàng Thị Thanh Hà
Khoa Thống kê – Tin học

Nội dung
1. Giới thiệu
2. Các cách duyệt cây
3. Cây nhị phân
4. Biểu diễn cây

1
4/17/2022

1. GIỚI THIỆU

Ví dụ Computer Company

Sales Manufacturing R&D

Canada International Laptops Desktops

Europe Asia US

1. ĐỊNH NGHĨA (1)


Cây là một tập hợp các nút (node), trong đó:
 một nút được phân biệt gọi là gốc (root)
 các nút còn lại được chia thành n thành phần (n>=0)
T1, …, Tn, mà mỗi phần là một cây.
T1, …, Tn, được gọi là cây con của root
 Quan hệ cha-con giữa các nút tạo nên cấu trúc

root

T1 T2 Tn

2
4/17/2022

1. ĐỊNH NGHĨA (2)


 Bậc của đỉnh: Số con của một đỉnh được gọi là bậc
của đỉnh đó.
 Đỉnh không có con được gọi là lá của cây.
 Đỉnh không phải là lá được gọi là đỉnh trong, lá
được gọi là đỉnh ngoài. Đỉnh gốc là đỉnh duy nhất
không có cha.
 Mức của đỉnh trong cây :
 Gốc của cây có mức là 0.
 Nếu mức của đỉnh cha là i thì mức của các đỉnh con là i
+ 1.
 Chiều cao của cây là mức cao nhất của các đỉnh
trong cây.

1. ĐỊNH NGHĨA (3)

 Ví dụ: với nút B thì,


 Cha là A
 Các nút con: E, F
 Nút ngang hàng: C, D
 Gốc: A
 Nút lá:
 K, L, F, G, M, I, J…

3
4/17/2022

1. ĐỊNH NGHĨA (4)


• Đường đi trong cây T là một dãy các đỉnh
< b1, b2, ..., bm > mà: bi là “cha” của bi + 1, 1
≤ i ≤ m -1.
• Cây T với bậc cao nhất của các đỉnh trong T
là m, được gọi là cây m - phân.
• Cây m-phân đầy đủ là cây mà mọi đỉnh trong
có đúng m con. a
a1 a2 ... ak

T1 T2 Tk

Cây tổng quát


7

1. Định nghĩa (5)


Định lý: Giả sử T là một cây m-phân.
- Nếu cây T có chiều cao h thì cây có nhiều nhất mh
lá.
- Nếu cây T có l lá thì cây có chiều cao h ≥ [logm l ].

4
4/17/2022

2. CÁC CÁCH DUYỆT CÂY


 Duyệt cây: Mục tiêu là đưa ra một danh sách
tuyến tính liệt kê tất cả các đỉnh của cây, mỗi
đỉnh một lần.
 Ba cách duyệt cây hay dùng:
- Duyệt theo thứ tự trước (pre-order search)
- Duyệt theo thứ tự giữa (in-order search)
- Duyệt theo thứ tự sau (post-order search)

2. CÁC CÁCH DUYỆT CÂY (2)

 Nếu cây T rỗng thì cả ba cách duyệt đều cho danh


sách rỗng.
 Nếu cây T chỉ có một đỉnh thì cả ba cách duyệt đều
cho danh sách gồm chỉ một đỉnh này.
 Nếu cây T có gốc a và các cây con T1, T2, ..., Tk thì:
1) Duyệt theo thứ tự trước của cây T: thăm gốc a rồi
sau đó là thăm cây con T1 theo thứ tự trước, rồi đến
thăm cây con T2 theo thứ tự trước .... Thăm cây con
Tk theo thứ tự trước:
a, (T1), (T2), … , (Tk)

10

5
4/17/2022

2. CÁC CÁCH DUYỆT CÂY (3)

2) Duyệt theo thứ tự sau của cây T:


(T1), (T2), … , (Tk), a

3) Duyệt theo thứ tự giữa của cây T:


(T1), a, (T2), … , (Tk)

11

2. CÁC CÁCH DUYỆT CÂY (4)


Ví dụ : Cho cây T 1

2 3 4

5 6 7 8

9 10

Duyệt theo thứ tự trước: 1, 2, 5, 6, 3, 4, 7, 9, 10, 8


Duyệt theo thứ tự giữa: 5, 2, 6, 1, 3, 9, 7, 10, 4, 8
Duyệt theo thứ tự sau: 5, 6, 2, 3, 9, 10, 7, 8, 4, 1.

12

6
4/17/2022

2. CÁC CÁCH DUYỆT CÂY (5)


Bài tập: Cho cây T

Hãy duyệt cây theo ba phương pháp: Duyệt theo


thứ tự trước, Duyệt theo thứ tự giữa, Duyệt theo
thứ tự sau.

13

2. CÁC CÁCH DUYỆT CÂY (5)


Thủ tục duyệt cây theo thứ tự giữa
Def Duyet_GIUA (a) ;
1. if a là lá:
print(a)
2. else
3. Duyet_GIUA (con bên trái nhất của a)
4. print(a)
5. for (mỗi một con c của a, trừ con bên trái
nhất, từ trái sang phải):
Duyet_GIUA (c)

14

7
4/17/2022

3. CÂY NHỊ PHÂN

 Định nghĩa: Cây nhị phân là cây mà mỗi đỉnh của


nó có không quá hai con.
Các cây con của một đỉnh của cây nhị phân
được phân biệt là cây con trái và cây con phải.
 Định lý : Số các cây nhị phân n đỉnh là
cn = C2nn / (2n +1).
Dãy số {cn} được gọi là dãy số Catalan.

15

3. CÂY NHỊ PHÂN (2)


 Một số ứng dụng của cây nhị phân
• Cây biểu thức
• Cây mã tiền tố

16

8
4/17/2022

3.1. CÂY BIỂU THỨC (1)


 Là cây nhị phân mà mỗi đỉnh của nó được gán nhãn
theo quy tắc:
 Các lá được gán các đại lượng
 Các đỉnh trong được gán các dấu phép toán của một biểu
thức nào đó.

17

3.1. CÂY BIỂU THỨC (2)

Xét biểu thức sau: E = (a + b) * (c - d).


Cây biểu thức tương ứng là:

18

9
4/17/2022

3.1. CÂY BIỂU THỨC (3)

 Duyệt cây biểu thức trên theo thứ tự sau, ta được danh
sách: a b + c d - *

 Đây là dạng Ba lan ngược của biểu thức E, giúp máy


tính tính được giá trị của biểu thức một cách nhanh
chóng nhờ một stack lưu giữ các đại lượng.

4/17/2022 19

3.1. STACK TÍNH GIÁ TRỊ BIỂU THỨC (4)

b c c c-d

a a a+b a+b a+b a+b E

a b + c d - *

4/17/2022 20

10
4/17/2022

3.1. STACK TÍNH GIÁ TRỊ BIỂU THỨC (4)

• Vẽ cây biểu diễn cho biểu thức


((a+b)+c*(d+e)+f)*(g+h)

• Trình bày biểu thức duyệt theo


thứ tự sau của biểu thức đã cho.

4/17/2022 21

3.2. CÂY MÃ TIỀN TỐ (1)

 Bài toán
Cho một tập các ký hiệu. Hãy mã hóa các ký hiệu này
bằng dãy các chữ số 0, 1 thoả mãn tính chất tiền tố,
nghĩa là không có mã của ký hiệu nào lại là tiền tố của
mã của ký hiệu khác.

22

11
4/17/2022

3.2. CÂY MÃ TIỀN TỐ (2)

Cách thực hiện


Xây dựng một cây nhị phân sao cho:
- Mỗi ký hiệu tương ứng với một lá,
- Cạnh xuống con trái của một đỉnh được gán nhãn 0
- Cạnh đi xuống con phải được gán nhãn 1.
=> Khi đó, dãy các nhãn trên đường đi từ gốc đến lá sẽ cho
mã tiền tố của ký hiệu tương ứng.
 Cây nhị phân xây dựng như trên được gọi là cây mã tiền
tố.

23

3.2. CÂY MÃ TIỀN TỐ (3): VÍ DỤ


 Các cây mã tiền tố:

0 1
0
1 1
0 1 0
0 1 0
c d e
1 0 0
0 1 0 1
kiểu dữ liệu trừu tượng cây
a b c d e a b

Các bộ mã tiền tố nhận Bộ


Ký hiệu được
mã 1là: Bộ mã 2
a 000 000
b 001 11
c 010 01
d 011 001
e 100 10

24

12
4/17/2022

4. Biểu diễn cây tổng quát bằng cây nhị phân (1)

 Nhược điểm của các cấu trúc cây tổng quát:


 Bậc của các nút trên cây có thể dao động trong một
biên độ lớn  việc biểu diễn gặp nhiều khó khăn và
lãng phí.
 Việc xây dựng các thao tác trên cây tổng quát phức
tạp hơn trên cây nhị phân nhiều.
 Vì vậy, thường nếu không quá cần thiết phải sử
dụng cây tổng quát, nên chuyển cây tổng quát
thành cây nhị phân.

4. Biểu diễn cây tổng quát bằng cây nhị phân (2)

 Có thể biến đổi một cây bất kỳ thành một cây


nhị phân theo qui tắc:
 Giữ lại nút con trái nhất làm nút con trái.
 Các nút con còn lại chuyển thành nút con phải của
nút con trái.
 Như vậy, trong cây nhị phân mới, con trái thể hiện
quan hệ cha con và con phải thể hiện quan hệ anh em
trong cây tổng quát ban đầu.

13
4/17/2022

4. Biểu diễn cây tổng quát bằng cây nhị phân (3)

 Giả sử có cây tổng quát được chuyển thành


cây nhị phân:
A
A

B C D E C

F H D

E F G H I J
G I

4. BIỂU DIỄN CÂY TỔNG QUÁT BẰNG CÂY NHỊ PHÂN (4)

 Ví dụ:

28

14
4/17/2022

5. kiểu dữ liệu trừu tượng (DLTT) cây: Các phép toán


 PARENT(n,T) cho nút cha của nút n trên T, nếu n là gốc thì hàm
trả về NULL.
 LEFTMOST_CHILD(n,T) cho nút con trái nhất của nút n trên T,
nếu n là lá thì hàm trả về NULL.
 RIGHT_SIBLING(n,T) cho nút ngang hàng phải của nút n trên T,
nếu n ko có anh em thì hàm trả về NULL.
 LABEL_NODE(n,T) trả về nhãn tại nút n của T.
 ROOT(T) trả về nút gốc, nếu T rỗng thì trả về NULL.
 CREATEi(v,T1,T2,..,Ti),với i=0..n, tạo cây mới có gốc là v & n
cây con T1,..,Tn. Nếu n=0 thì cây mới chỉ có 1 nút gốc duy nhất.
 DuyetCay(T)

5. Cây: biểu diễn bằng mảng (1)

Sử dụng 2 mảng một chiều có kích thước n để chứa n nút:


 Cho cây T có n nút được gán nhãn lần lượt là 0,1, 2, ..,
n-1.
 Dùng một mảng một chiều A để lưu trữ cây bằng cách
cho A[i] = j với j là nút cha của nút i. Nếu i là gốc ta
cho A[i] = -1.
 Nếu cây T là cây có nhãn thì dùng thêm một mảng một
chiều thứ hai L chứa các nhãn của cây bằng cách cho
L[i] = x với x là nhãn của nút i.

15
4/17/2022

6. cây: biểu diễn bằng mảng (2)


A/0
Ví dụ: B/1 C/2

D/3 E/4 H/7 J/8

F/5 G/6

A B C D E F G H I … Nhãn
-1 0 0 1 1 4 4 2 2 … Nút cha
0 1 2 3 4 5 6 7 8 … Chỉ số mảng

def __init__(self, data):

5. cây: biểu diễn bằng mảng (3)

Class treeNode:
def __init__(self):
Data=[] // lưu nhãn
NodeParent=[] // lưu nút cha
Size=0 // số nút của cây

T= treeNode()

16
4/17/2022

5. cây: biểu diễn bằng mảng (4)

Các phép toán cơ bản:


Kiểm tra cây rỗng

def EmptyTree(T):
return T. Size == 0
}

5. cây: biểu diễn bằng mảng (5)


Xác định nút cha của nút trên cây
Def Parent(n, T):
if T.EmptyTree() is True:
return None
else
return T.Parent[n]

Xác định nhãn của nút trên cây


def Label_Node(n,T):
if T.EmptyTree() is False:
return T.Data[n]

17
4/17/2022

5. biểu diễn bằng mảng: Xác định con trái nhất


Def LeftMostChild(n,T):
found
if (n<0):
return None
i=n+1 //Vị trí nút đầu tiên hy vọng là con của n
found=0
while ((i<=T.Size-1) and found is False)
if (T.Parent[i]==n):
found=1 //Tìm thấy con trái nhất của n
else:
i=i+1
if (found):
return i
else:
return None

5. cây: biểu diễn bằng mảng (7)


Xác định nút cha của nút trên cây
def Root(T):
if (T.EmptyTree()is False):
return 0
else:
return None

18
4/17/2022

5.biểu diễn bằng mảng: Xác định anh em ruột phải


def RightSibling(n, T)
if (n<0):
return None
parent=T.Parent[n]
i=n+1
found=0
while ((i<=T.Size-1) and found is False)
if (T.Parent[i]==parent):
found=1
else:
i=i+1
if (found):
return i
else: return None

5. biểu diễn bằng mảng: duyệt theo thứ tự trước


def PreOrder(n, T):
print("%c ",Label_Node(n,T))
i=LeftMostChild(n,T)
while (i!=0):
PreOrder(i,T)
i=RightSibling(i,T)

19
4/17/2022

5. biểu diễn bằng mảng (10)


def CreateTree(self):
self.Size=int(input( “How many node"))
self.Data[0] =input( “Root label? ")
self.Parent[0]=-1 /* nut goc khong co cha
*/
for i in range(1, self.Size):
self.Parent[i]=input( “parent’s ",i)
self.Data[i]=input(“Label’s ",i)

5. Biểu diễn cây tổng quát bằng cây nhị phân (1)

Khai báo cấu trúc dữ liệu cây nhị phân


như sau :

class Node:
def __init__(self, data):
self.data = data
self.left = None
self.right = None

element
left child right sibling

20
4/17/2022

5. Biểu diễn cây tổng quát bằng cây nhị phân (2)
class Node:
….

def addLeft(self, dataLeft):


if self.data:
self.left=Node(dataLeft)
else:
self.data=dataLeft

def addRight(self, dataRight):


if self.data:
self.right=Node(dataRight)
else:
self.data= dataRight

5. Biểu diễn cây tổng quát bằng cây nhị phân (1)

class Node:
def __init__(self, data):
self.left = None
self.right = None
self.data = data

Root=Node(10)
Root.addLeft(34)
Root.addRight(89)
Root.left.addLeft(45)
Root.addRight(89)
Root.left.addRight(50)

21
4/17/2022

5. Biểu diễn cây tổng quát bằng cây nhị phân (3)

 Có 3 kiểu duyệt chính có thể áp dụng trên cây


nhị phân:
 Duyệt theo thứ tự trước (NLR)
 Duyệt theo thứ tự giữa (LNR)
 Duyệt theo thứ tự sau (LRN).
 Tên của 3 kiểu duyệt này được đặt dựa trên trình
tự của việc thăm nút gốc so với việc thăm 2 cây
con.

5. Biểu diễn cây tổng quát bằng cây NP: Duyệt theo thứ tự trước
 Kiểu duyệt này trước tiên thăm nút gốc sau đó thăm
các nút của cây con trái rồi đến cây con phải.

def NLR(root)
if (Root != None):
print(root.data)
NLR(root.left)
NLR(root.right)

22
4/17/2022

5. Biểu diễn cây tổng quát bằng cây NP (5): Duyệt theo thứ tự giữa
 Kiểu duyệt này trước tiên thăm các nút của cây con
trái sau đó thăm nút gốc rồi đến cây con phải.
def LNR(root)
if (Root != None):
LNR(root.left)
print(root.data)
LNR(root.right)

5. Biểu diễn cây tổng quát bằng cây nhị phân (6)
Duyệt theo thứ tự sau (Left-Right-Node)
 Kiểu duyệt này trước tiên thăm các nút của cây con trái sau đó thăm đến
cây con phải rồi cuối cùng mới thăm nút gốc.
def LRN(root)
if (Root != None):
LRN(root.left)
LRN(root.right)
print(root.data)

23
4/17/2022

5. Biểu diễn cây tổng quát bằng cây nhị phân (7)
Một cách biểu diễn cây nhị phân khác

 Khi định nghĩa cây NP, khi người ta quan tâm


cả quan hệ 2 chiều cha con chứ không chỉ một
chiều thì cấu trúc cây NP có thể định nghĩa lại:
class Node:
def __init__(self, data):
self.parent = None // thêm nút cha
self.left = None
self.right = None
self.data = data

24

You might also like