Tải bản đầy đủ (.ppt) (70 trang)

hoa cuong có thì sử dụng – thích thì lao vào

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 (206.92 KB, 70 trang )

<span class='text_page_counter'>(1)</span><div class='page_container' data-page=1></div>
<span class='text_page_counter'>(2)</span><div class='page_container' data-page=2>

2


Cây



• Định nghĩa:


• Rỡng là 1 cây


• T1 , T2 , ……Tm là cây thi


là cây (m-phân)


• T1 , T2 , ……Tm gọi là cây con của cây T
T


T<sub>m</sub>
T<sub>2</sub>


</div>
<span class='text_page_counter'>(3)</span><div class='page_container' data-page=3>

• Ví dụ


– Cây thư mục trong hệ điều hành
– Cây gia phả của 1 dòng họ


– Cây biểu thức: a-b+c*d/e


+


- /


</div>
<span class='text_page_counter'>(4)</span><div class='page_container' data-page=4>

4



Mợt sớ khái niệm



• R là cha của U, O, P
• U, O, P là con của R


• Q, R là đỉnh trước của A.
• A là đỉnh sau của Q, R


• T, Y, U, O, A là các nút lá (khơng có con)
• Q là nút gốc


Q


E R


w


Y


T U O P


A


mức 1


mức 2


mức 3


</div>
<span class='text_page_counter'>(5)</span><div class='page_container' data-page=5>

Phép duyệt




• Phép duyệt: Đưa ra tất cả các nút theo
mợt thứ tự nào đó, mỡi nút 1 lần


– Ví dụ: Tim kiếm một file hay một folder trong
cây thư mục


• Phổ biến:


– Duyệt theo bề sâu (Depth First Search - DFS)
– Duyệt theo bề rộng (Breadth First Search -


</div>
<span class='text_page_counter'>(6)</span><div class='page_container' data-page=6>

6


Cây nhị phân (Binary tree)



• Là cây bao gờm các nút, mỡi nút có tới đa 2 cây
con:


– Cây con bên trái (Left)
– Cây con bên phải (Right)
• Mơ tả cấu trúc:


<i><b>typedef struct nodet {</b></i>
<i><b>elem data;</b></i>


<i><b>struct nodet *left, *right;</b></i>
<i><b>} node;</b></i>


</div>
<span class='text_page_counter'>(7)</span><div class='page_container' data-page=7>

Duyệt theo bề sâu (DFS)




<i>• Duyệt tiền tự (Preorder Search – NLR)</i>


<i>– Thăm nút gốc (Node)</i>


<i>– Duyệt cây con bên trái (Left)</i>


<i>– Duyệt cây con bên phải (Right) </i>


<i>• Duyệt trung tự (Inorder Search – LNR)</i>
(tương tự)


</div>
<span class='text_page_counter'>(8)</span><div class='page_container' data-page=8>

8


Duyệt theo bề sâu (DFS)



• NLR: QWTYRUPA
• LNR: TWYQURAP
• LRN: TYWUAPRQ


Q


R
w


Y


T U P


</div>
<span class='text_page_counter'>(9)</span><div class='page_container' data-page=9>

<i>Ví dụ: Đếm số nút trên cây</i>




<i><b>int sonut(tree t)</b></i>
<i><b>{</b></i>


<i><b>if (t==NULL) return 0;</b></i>


</div>
<span class='text_page_counter'>(10)</span><div class='page_container' data-page=10>

10


<i>Độ cao cây?</i>



<i><b>int h(tree t)</b></i>
<i><b>{</b></i>


<i><b>if (t==NULL) return 0;</b></i>


<i><b>return 1 + max(h(t->left), h(t->right));</b></i>
<i><b>}</b></i>


</div>
<span class='text_page_counter'>(11)</span><div class='page_container' data-page=11>

<i>Nhập cây số nguyên>0</i>



<i><b>void nhap(tree &t)</b></i>
<i><b>{</b></i>


<i><b>int x;</b></i>
<i><b>cin>>x;</b></i>
<i><b>if (x>0)</b></i>
<i><b>{</b></i>


<i><b>t = new node;</b></i>
<i><b>t->data = x;</b></i>


<i><b>nhap(t->left);</b></i>
<i><b>nhap(t->right);</b></i>
<i><b>}</b></i>


<i><b>else</b></i>


<i><b>t = NULL;</b></i>


• Với cây trên dữ liệu nhập:


<i>7 2 4 0 0 5 0 0 6 </i>
<i> 3 0 0 9 8 0 </i>
<i> 0 0</i>


7


6
2


5


4 3 9


</div>
<span class='text_page_counter'>(12)</span><div class='page_container' data-page=12>

12


<i>In cây (số nguyên)</i>



<i><b>void incay(tree t, int m=1)</b></i>
<i><b>{</b></i>



<i><b>if (t!=NULL)</b></i>
<i><b>{</b></i>


<i><b>incay(t->left, m+1);</b></i>


<i><b>cout<<endl<<setw(4*m)<<t->data;</b></i>
<i><b>incay(t->right, m+1);</b></i>


</div>
<span class='text_page_counter'>(13)</span><div class='page_container' data-page=13>

<i>Xóa toàn bộ cây</i>



<i><b>void xoacay(tree &t)</b></i>
<i><b>{</b></i>


<i><b>if (t!=NULL)</b></i>
<i><b>{</b></i>


<i><b>xoacay(t->left);</b></i>
<i><b>xoacay(t->right);</b></i>
<i><b>delete t;</b></i>


</div>
<span class='text_page_counter'>(14)</span><div class='page_container' data-page=14>

14


<i>Đếm số nút lá trên cây</i>



<i><b>int sonutla(tree t)</b></i>
<i><b>{</b></i>


<i><b>if (t==NULL) return 0;</b></i>


<i><b>if (t->left==NULL && t->right==NULL)</b></i>


<i><b>return 1;</b></i>


</div>
<span class='text_page_counter'>(15)</span><div class='page_container' data-page=15>

<i>Đếm số nút có 1 con trên cây</i>



<i><b>int sonut1(tree t)</b></i>
<i><b>{</b></i>


<i><b>if (t==NULL) return 0;</b></i>


<i><b>if ((t->left!=NULL) &&( t->right==NULL))</b></i>
<i><b>return 1+sonut1(t->left);</b></i>


<i><b>if ((t->left==NULL) &&( t->right!=NULL))</b></i>
<i><b>return 1+sonut1(t->right);</b></i>


</div>
<span class='text_page_counter'>(16)</span><div class='page_container' data-page=16>

16


<i>Đếm số nút có 1 con trên cây</i>



<i><b>int sonut1(tree t)</b></i>
<i><b>{</b></i>


<i><b>if (t==NULL) return 0;</b></i>


<i><b>if ((t->left!=NULL && t->right==NULL)||</b></i>
<i><b> (t->left==NULL && t->right!=NULL)) </b></i>
<i><b>return 1+sonut1(t->left) +sonut1(t->right);</b></i>
<i><b>return sonut1(t->left)+sonut1(t->right);</b></i>


</div>
<span class='text_page_counter'>(17)</span><div class='page_container' data-page=17>

<i>Đếm số nút có 1 con trên cây</i>




<i><b>int sonut1(tree t)</b></i>
<i><b>{</b></i>


<i><b>if (t==NULL) return 0;</b></i>


<i><b>if ((t->left==NULL) ^( t->right==NULL))</b></i>


<i><b>return 1+sonut1(t->left)+sonut1(t->right);</b></i>
<i><b>return sonut1(t->left)+sonut1(t->right);</b></i>


</div>
<span class='text_page_counter'>(18)</span><div class='page_container' data-page=18>

18


<i>Đếm số nút trong trên cây (không </i>


<i>phải là lá)</i>



<i><b>int sonuttrg(tree t)</b></i>
<i><b>{</b></i>


<i><b>if (t==NULL) return 0;</b></i>


<i><b>if (t->left==NULL && t->right==NULL)</b></i>
<i><b>return 0;</b></i>


</div>
<span class='text_page_counter'>(19)</span><div class='page_container' data-page=19>

Tính trung binh cộng



<i><b>void NLR(tree t, int &sn, int &tg)</b></i>
<i><b>{</b></i>


<i><b>if (t!=NULL)</b></i>


<i><b>{</b></i>


<i><b>tg+=t->data;</b></i>
<i><b>sn++;</b></i>


<i><b>NLR(t->left, sn, tg);</b></i>
<i><b>NLR(t->right, sn, tg);</b></i>
<i><b>}</b></i>


<i><b>}</b></i>


<i><b>float tbc(tree t)</b></i>
<i><b>{</b></i>


<i><b>int sn, tg;</b></i>
<i><b>sn = tg = 0;</b></i>


<i><b>NLR(t, sn, tg);</b></i>


</div>
<span class='text_page_counter'>(20)</span><div class='page_container' data-page=20>

20


Bài tập



• Đếm sớ nút trên mức thứ k
• Đếm sớ nút trên mức >= k
• Đếm số nút trên mức <= k


</div>
<span class='text_page_counter'>(21)</span><div class='page_container' data-page=21>

Đếm số nút trên mức lẻ của cây



<i><b>int muccl(tree t, int m=1)</b></i>


<i><b>{</b></i>


<i><b>if (t==NULL) return 0;</b></i>


<i><b>return m%2 +muccl(t->left, m+1) +</b></i>


<i><b>muccl(t->right, m+1);</b></i>
<i><b>}</b></i>


<i><b>Gọi hàm:</b></i>


<i><b>cout<<“Số nút trên mức lẻ =“<<muccl(t);</b></i>


</div>
<span class='text_page_counter'>(22)</span><div class='page_container' data-page=22>

22


Đếm số nút trên mức thứ k



<i><b>int nutk(tree t, int k)</b></i>
<i><b>{</b></i>


<i><b>if (t==NULL) return 0;</b></i>
<i><b>if (k>1)</b></i>


<i><b>return nutk(t->left,k-1)+nutk(t->right, k-1);</b></i>
<i><b>return 1;</b></i>


</div>
<span class='text_page_counter'>(23)</span><div class='page_container' data-page=23>

void nlr(tree t, int k, int &sn, int &tg)
{
if (t!=NULL)
{


if (k>1)
{


nlr(t->left, k-1, sn, tg);
nlr(t->right, k-1, sn, tg);
}
else
{
sn++;
tg +=t->data);
}
}
}


<i><b>float tbc(tree t, int k)</b></i>
<i><b>{</b></i>


<i><b>int sn, tg;</b></i>
<i><b>sn = tg = 0;</b></i>


<i><b>nlr(t, k, sn, tg);</b></i>


</div>
<span class='text_page_counter'>(24)</span><div class='page_container' data-page=24>

24


void nlr(tree t, int k, int &sn, int &tg)
{
if (t!=NULL)
{
sn++;
tg +=t->data);


if (k>1)
{


nlr(t->left, k-1, sn, tg);
nlr(t->right, k-1, sn, tg);
}


}
}


<i><b>float tbc(tree t, int k)</b></i>
<i><b>{</b></i>


<i><b>int sn, tg;</b></i>
<i><b>sn = tg = 0;</b></i>


<i><b>nlr(t, k, sn, tg);</b></i>


<i><b>if (sn == 0) return </b></i>
<i><b>0.;</b></i>


</div>
<span class='text_page_counter'>(25)</span><div class='page_container' data-page=25>

void nlr(tree t, int k, int &sn, int
&tg)
{
if (t!=NULL)
{
if (k<=1)
{
sn++;
tg +=t->data);


}


nlr(t->left, k-1, sn, tg);


nlr(t->right, k-1, sn,
tg);


}
}


<i><b>float tbc(tree t, int k)</b></i>
<i><b>{</b></i>


<i><b>int sn, tg;</b></i>
<i><b>sn = tg = 0;</b></i>


<i><b>nlr(t, k, sn, tg);</b></i>


<i><b>if (sn == 0) return </b></i>
<i><b>0.;</b></i>


</div>
<span class='text_page_counter'>(26)</span><div class='page_container' data-page=26>

26


Dụt theo bề rợng (BFS)



• Hay còn gọi là dụt theo mức
• Sử dụng hàng đợi: Tuần tự từ
mức thấp đến cao, từ trái qua
phải



• Với cây trên ta có thứ tự các
nút được duyệt lần lượt:


Q W R T Y U P A
SV cài đặt như bài tập


Q


R
w


Y


T U P


</div>
<span class='text_page_counter'>(27)</span><div class='page_container' data-page=27>

<i>1. Khởi tạo hàng đợi q rỗng</i>
<i>2. M=0; p=NULL;</i>


<i>3. Nếu t!=NULL</i>
• <i>Đưa p vào q</i>


• <i>Đưa t vào q</i>


<i>4. Khi q!=rỗng</i>


• <i>Lấy p ra khỏi q</i>


• <i><sub>Nếu p==NULL</sub></i>
 <i><sub>Nếu q!=rỗng</sub></i>



• <i>M = M+1;</i>


• <i>Đưa p vào q</i>


• <i>//Xử lý</i>


• <i>Ngược lại</i>


 <i><sub>Xử lý p->data</sub></i>


</div>
<span class='text_page_counter'>(28)</span><div class='page_container' data-page=28>

28


Cây tim kiếm nhị phân



<b> (Binary Search Tree – BST)</b>



• Ý nghĩa: Phục vụ tim kiếm nhị phân trên cấu
trúc đợng


• Định nghĩa: Là cây nhị phân thỏa điều kiện mọi
nút đều có khóa


</div>
<span class='text_page_counter'>(29)</span><div class='page_container' data-page=29>

BST



7


11
3


5



1 9 15


</div>
<span class='text_page_counter'>(30)</span><div class='page_container' data-page=30>

30


Chèn phần tử vào BST



• Thêm 12




20


10


15
5


30


25 40


35
12<


12>


12<


12



</div>
<span class='text_page_counter'>(31)</span><div class='page_container' data-page=31>

Chèn phần tử vào BST



<i><b>void inserttree(tree &t, elem x)</b></i>
<i><b>{</b></i>


<i><b>if (t==NULL)</b></i>
<i><b>{</b></i>


<i><b>t = new node;</b></i>
<i><b>t->data = x;</b></i>


</div>
<span class='text_page_counter'>(32)</span><div class='page_container' data-page=32>

32


Nhập cây (số nguyên >0)



<i><b>t = NULL;</b></i>
<i><b>do {</b></i>


<i><b>cin>>x;</b></i>
<i><b>if (x>0)</b></i>


</div>
<span class='text_page_counter'>(33)</span><div class='page_container' data-page=33>

Xóa phần tử trên BST



• Xóa 15


20


10



15
5


30


25 40


35
15<


15>


15=


</div>
<span class='text_page_counter'>(34)</span><div class='page_container' data-page=34>

34
• Xóa 20


20


10


15
5


30


25 40


</div>
<span class='text_page_counter'>(35)</span><div class='page_container' data-page=35>

<i><b>void deletetree(tree &t, elem x)</b></i>
<i><b>{</b></i>


<i><b>if (t!=NULL)</b></i>
<i><b> if (x<t->data)</b></i>
<i><b> deletetree(t->left, x);</b></i>
<i><b> else</b></i>
<i><b>if (x>t->data)</b></i>
<i><b> deletetree(t->right, x);</b></i>
<i><b>else</b></i>
<i><b>{</b></i>


<i><b> tree q = t;</b></i>


<i><b> if (t->right==NULL)</b></i>
<i><b>t = t->left;</b></i>


<i><b> else</b></i>


<i><b>if (t->left==NULL)</b></i>
<i><b> t = t->right;</b></i>
<i><b>else</b></i>


</div>
<span class='text_page_counter'>(36)</span><div class='page_container' data-page=36>

36
Tim phần tử thay thế (phần tử lớn nhất)


<i><b>void del(tree &r, tree &q)</b></i>
<i><b>{</b></i>


<i><b>if (r->right!=NULL)</b></i>
<i><b>del(r->right, q);</b></i>


<i><b>else</b></i>


<i><b>{</b></i>


<i><b>q->data = r->data;</b></i>
<i><b>q = r;</b></i>


</div>
<span class='text_page_counter'>(37)</span><div class='page_container' data-page=37>

Tim kiếm phần tử trên BST



</div>
<span class='text_page_counter'>(38)</span><div class='page_container' data-page=38>

38


Tim kiếm phần tử x



<i><b>tree searchtree(tree t, elem x)</b></i>
<i><b>{</b></i>


<i><b>if (t==NULL)</b></i>


<i><b>return NULL;</b></i>
<i><b>if (x<t->data)</b></i>


<i><b>return searchtree(t->left, x);</b></i>
<i><b>if (x>t->data)</b></i>


<i><b> return searchtree (t->right, x);</b></i>
<i><b>return t;</b></i>


</div>
<span class='text_page_counter'>(39)</span><div class='page_container' data-page=39>

Cắt cây có gớc x



<i><b>tree cuttree(tree &t, elem x)</b></i>
<i><b>{</b></i>



<i><b>if (t==NULL)</b></i>
<i><b>return NULL;</b></i>
<i><b>if (x<t->data)</b></i>


<i><b>return cuttree (t->left, x);</b></i>
<i><b> if (x>t->data)</b></i>


<i><b> return cuttree (t->right, x);</b></i>
<i><b>{</b></i>


</div>
<span class='text_page_counter'>(40)</span><div class='page_container' data-page=40>

40


<i><b>void ink(tree t, int &k)</b></i>
<i><b>{</b></i>


<i><b>if (t!=NULL)</b></i>
<i><b>{</b></i>


<i><b>if (k>0)</b></i>


<i><b>ink(t->right, k);</b></i>
<i><b>if (k>0)</b></i>


<i><b>{</b></i>


<i><b>cout<<setw(4)<<t->data;</b></i>
<i><b>k--;</b></i>


<i><b>}</b></i>



<i><b>if (k>0)</b></i>


<i><b>ink(t->left, k);</b></i>
<i><b>}</b></i>


</div>
<span class='text_page_counter'>(41)</span><div class='page_container' data-page=41></div>
<span class='text_page_counter'>(42)</span><div class='page_container' data-page=42>

42
• Đưa vào cây:1, 2, 3, …, n


1


2


3


</div>
<span class='text_page_counter'>(43)</span><div class='page_container' data-page=43>

Định nghĩa



</div>
<span class='text_page_counter'>(44)</span><div class='page_container' data-page=44>

44


Định nghĩa



</div>
<span class='text_page_counter'>(45)</span><div class='page_container' data-page=45>

Biểu diễn cây



</div>
<span class='text_page_counter'>(46)</span><div class='page_container' data-page=46>

46


Tổ chức cấu trúc dữ liệu



• Tương tự như BST, tuy nhiên mỗi node cần bổ
<i><b>sung một vùng bal (balance), ghi nhận trạng </b></i>
thái cân bằng tại node đó:



</div>
<span class='text_page_counter'>(47)</span><div class='page_container' data-page=47>

Mơ tả cấu trúc dữ liệu



<i><b>typedef struct nodet {</b></i>
<i><b>elem data;</b></i>


<i><b>struct nodet *left, *right;</b></i>
<i><b>int bal;</b></i>


<i><b>} node;</b></i>


</div>
<span class='text_page_counter'>(48)</span><div class='page_container' data-page=48>

48


Trạng thái cân bằng tại 1 node



• Tại p có 3 trường hợp:


p->bal = 1 p->bal = 0 p->bal = -1


</div>
<span class='text_page_counter'>(49)</span><div class='page_container' data-page=49>

a) Trường hợp p->bal = 1



• Thêm vào làm cho h<sub>R</sub> tăng


hoặc xóa làm cho hL giảm


Đặt p1 = p->right
phép quay:


<i><b> p->right=p1->left</b></i>
<i><b> p1->left =p</b></i>



p


p1 p


</div>
<span class='text_page_counter'>(50)</span><div class='page_container' data-page=50>

50


a1) Trường hợp p1->bal = 1



• Thêm vào làm cho hR tăng


hoặc xóa làm cho hL giảm


phép quay đơn:
<i><b> p->right=p1->left</b></i>
<i><b> p1->left =p</b></i>


<i><b>p->bal =0</b></i>
<i><b>p1->bal=0</b></i>
<i><b>p = p1</b></i>


p


p1 p


</div>
<span class='text_page_counter'>(51)</span><div class='page_container' data-page=51>

a2) Trường hợp p1->bal = 0



• Chỉ xảy ra khi xóa làm cho h<sub>L</sub> giảm


phép quay đơn:



<i><b> p->right=p1->left</b></i>
<i><b> p1->left =p</b></i>


<i><b>p->bal =1</b></i>
<i><b>p1->bal=-1</b></i>


p


p1 p


</div>
<span class='text_page_counter'>(52)</span><div class='page_container' data-page=52>

52


a3) Trường hợp p1->bal = -1



• Khơng sử dụng phép quay đơn được vi sẽ mất cân
bằng


phép quay đơn:


<i><b> p->right=p1->left</b></i>
<i><b> p1->left =p</b></i>


p1
p


p


</div>
<span class='text_page_counter'>(53)</span><div class='page_container' data-page=53>

a3) Trường hợp p1->bal = -1



• Đặt p2 = p1->left



Sử dụng phép quay kép


<i> </i> <i><b>p->right=p2->left</b></i>
<i><b> p2->left=p</b></i>


<i><b> p1->left=p2->right</b></i>
<i><b> p2->right=p1</b></i>


<i><b>p->bal=(p2->bal==1? -1: 0)</b></i>
<i><b>p1->bal=(p2->bal==-1? 1: 0)</b></i>


p


p1


p2


p2


</div>
<span class='text_page_counter'>(54)</span><div class='page_container' data-page=54>

54


b) Trường hợp p->bal = -1



• Trường hợp này đới xứng với trường hợp
a), chính vi vậy ta chỉ cần thay


– left thành right và ngược lại


</div>
<span class='text_page_counter'>(55)</span><div class='page_container' data-page=55>

Chèn phần tử vào AVL




• Tương tự như BST, tuy nhiên sau khi


chèn cây sẽ tăng độ cao, sử dụng biến h
để ghi nhận cây có tăng đợ cao hay


</div>
<span class='text_page_counter'>(56)</span><div class='page_container' data-page=56>

56


Ví dụ minh họa



• Thêm lần lượt 3, 5 và 7


3 1


5 <sub>7</sub>


3 1


5 0


0


5 0


7 0


3
0


Thêm 7



Mất cân bằng tại 3


Sử dụng quay đơn …và cân bằng


7


3 1


5 1


</div>
<span class='text_page_counter'>(57)</span><div class='page_container' data-page=57>

Ví dụ minh họa



Thêm 12, 10


5 1


7 1


3
0


12 0


10 0


Thêm 10


5 1



7 1


3
0


12 -1


10 0


</div>
<span class='text_page_counter'>(58)</span><div class='page_container' data-page=58>

58


Ví dụ minh họa



• Thêm 11


5 1


10 0/1


3
0


12 0/-1


7
0
11 0
-1
5
0


10
3
0
12
7


0 11 0


</div>
<span class='text_page_counter'>(59)</span><div class='page_container' data-page=59>

• Thêm 8, 9 ?


-1


5


0
10


3
0


12


7


0 11 0


</div>
<span class='text_page_counter'>(60)</span><div class='page_container' data-page=60>

60


<i><b>void insertAVL(AVLtree &p, elem </b></i>
<i><b>x, int &h)</b></i>


<i><b>{</b></i>


<i><b>if (p==NULL)</b></i>
<i><b>{</b></i>


<i><b>p = new node;</b></i>
<i><b>p->data = x;</b></i>


<i><b>p->left = p->right = NULL;</b></i>
<i><b>p->bal=0;</b></i>
<i><b>h=1;</b></i> <i><b>//true</b></i>
<i><b>}</b></i>
<i><b>else</b></i>
<i><b>if (x<p->data)</b></i>
<i><b>{</b></i>


<i><b>insertAVL(p->left, x, h);</b></i>


<i><b>if (h) </b><b>Xem lại cân bằng trái tại p;</b></i>


<i><b>}</b></i>
<i><b>else</b></i>


<i><b>if (x>p->data)</b></i>
<i><b>{</b></i>


<i><b>insertAVL(p->right, x, h);</b></i>
<i><b> </b></i> <i><b>if (h) </b><b>Xem lại cân bằng </b></i>


<i><b>phải tại p;</b></i>



<i><b>}</b></i>
<i><b>else</b></i>


</div>
<span class='text_page_counter'>(61)</span><div class='page_container' data-page=61>

Xem lại thế cân bằng trái



<i><b>switch (p->bal)</b></i>
<i><b>{</b></i>


<i><b>case 1: p->bal = 0; h = 0; break;</b></i>
<i><b>case 0: p->bal = -1; break;</b></i>


<i><b>case -1:</b></i>


<i><b>{</b></i> <i><b>AVLtree p1 = p->left;</b></i>
<i><b>if (p1->bal ==-1)</b></i>


<i><b>{</b></i>


<i><b> p->left = p1->right;</b></i>
<i><b> p1->right = p;</b></i>


<i><b> p->bal = 0;</b></i>


<i><b> p = p1; //p->bal =0; h=0</b></i>
<i><b>}</b></i>


<i><b>else</b></i>
<i><b>{</b></i>



<i><b>AVLtree p2 = p1->right;</b></i>
<i><b>p->left = p2->right;</b></i>


<i><b>p2->right = p;</b></i>


<i><b>p1->right = p2->left;</b></i>
<i><b>p2->left = p1;</b></i>


<i><b>p->bal = (p2->bal==-1?1:0);</b></i>
<i><b>p1->bal = (p2->bal==1?-1:0);</b></i>
<i><b>p = p2; //p->bal =0; h=0</b></i>


<i><b>}</b></i>


<i><b>p->bal = 0;</b></i>
<i><b>h = 0;</b></i>


</div>
<span class='text_page_counter'>(62)</span><div class='page_container' data-page=62>

62


Xem lại thế cân bằng phải



• Trường hợp này đới xứng với trường hợp
xem lại thế cân bằng trái, chính vi vậy ta
chỉ cần thay


– left thành right và ngược lại


– 1 thành -1 và ngược lại


</div>
<span class='text_page_counter'>(63)</span><div class='page_container' data-page=63>

Xóa phần tử



Xóa 35
0
0
5
0
10
12
7


0 11 0


1
20
25
-1
30
23 0
35
27 0
0
6


0 9 0


3


-1


</div>
<span class='text_page_counter'>(64)</span><div class='page_container' data-page=64>

64



5


0
10


12


7


0 11 0


1


20


23


1
25


30


27 0


0


6


0 9 0



3


-1


</div>
<span class='text_page_counter'>(65)</span><div class='page_container' data-page=65>

Xóa phần tử


Xóa 35
0
0
5
-1
10
12
7


0 11 0


1
20
25
-1
30
23 0
35
-1
6


0 9 0


3



-1


</div>
<span class='text_page_counter'>(66)</span><div class='page_container' data-page=66>

66
• Mất cân bằng tại 20


20


23


1
25


30
0


-1


5


-1
10


12


7


0 11 0


1



6


0 9 0


3


</div>
<span class='text_page_counter'>(67)</span><div class='page_container' data-page=67>

0
10


20


12


-1


0


5 1


7
0


6


0 9


3


0



23


0
25


30
0


</div>
<span class='text_page_counter'>(68)</span><div class='page_container' data-page=68>

68


Xóa phần tử trên AVL



<i><b>void deleteAVL(AVLtree &p, elem x, int &h)</b></i>
<i><b>{</b></i>


<i><b>if (p==NULL)</b></i>
<i><b> h = 0;</b></i>
<i><b>else</b></i>


<i><b> if (x<p->data)</b></i>
<i><b> {</b></i>


<i><b> deleteAVL(p->left, x, h);</b></i>


<i><b> if (h) </b><b>Xem lại thê cân bằng trái tại p</b></i>


<i><b> }</b></i>
<i><b> else</b></i>


<i><b>if (x>p->data)</b></i>


<i><b>{</b></i>


<i><b> deleteAVL(p->right, x, h);</b></i>
<i><b> if (h)</b></i>


<i><b>Xem lại thê cân bằng phải tại p</b></i>


<i><b>}</b></i>


<i><b>else</b></i>
<i><b>{</b></i>


<i><b> AVLtree q = p;</b></i>


<i><b> if (p->right==NULL)</b></i>
<i><b> {</b></i>


<i><b>p = p->left;</b></i>
<i><b>h = 1;</b></i>


<i><b> }</b></i>
<i><b> else</b></i>


<i><b>if (p->left==NULL)</b></i>
<i><b>{</b></i>


<i><b> p = p->right;</b></i>
<i><b> h = 1;</b></i>


<i><b>}</b></i>


<i><b>else</b></i>
<i><b>{</b></i>


<i><b> del(p->left, q, h);</b></i>
<i><b> if (h)</b></i>


<i><b> </b><b>Xem lại thê cân bằng trái tại p</b><b> </b></i>


<i><b> }</b></i>
<i><b> delete q;</b></i>
<i><b>}</b></i>


</div>
<span class='text_page_counter'>(69)</span><div class='page_container' data-page=69>

Tim phần tử thay thế



<i><b>void del(AVLtree &r, AVLtree &q, int &h)</b></i>
<i><b>{</b></i>


<i><b>if (r->right!=NULL)</b></i>
<i><b>{</b></i>


<i><b>del(r->right, q, h);</b></i>


<i><b>if (h) </b><b>Xem lại thê cân bằng phải tại r</b></i>


<i><b>}</b></i>
<i><b>else</b></i>
<i><b>{</b></i>


<i><b>q->data = r->data;</b></i>
<i><b>q = r;</b></i>



<i><b>r = r->left;</b></i>
<i><b>h = 1;</b></i>


</div>
<span class='text_page_counter'>(70)</span><div class='page_container' data-page=70>

70


Kiểm tra 10%


(đến 11g30)



• Minh họa quá trinh hinh thành cây AVL khi
thêm lần lượt các giá trị sau vào cây (chỉ rõ
phép quay- nếu có):


</div>

<!--links-->

×