You are on page 1of 3

tags:

DSA

Trình bày (bằng ngôn ngữ tựa C) giải thuật loại bỏ 1 nút có giá
trị X trên cây nhị phân tìm kiếm. Chi phí thời gian trung bình của
giải thuật này có lớn hơn giải thuật tìm kiếm rồi bổ sung hay
không, vì sao? Mỗi nút trên cây có cấu trúc như sau:
P_L Trỏ tới cây con trái
KEY Chứa giá trị khoá
P_R Trỏ tới cây con phải

Giải thuật
BST_Delete(T, x)
{
P = T;
Q = NULL; //Q luôn là cha của P
while(P != NULL) //Tìm xem có khoá x trên cây không
{
if(P->KEY == x) //Tìm thấy, P trỏ vào nút cần xoá
{
break;
}
Q = P;
if(x < P->KEY)
{
P = P->P_L;
}
else
{
P = P->P_R;
}
}
if(P == NULL) //x không có trên cây
{
return;
}
if(P->P_L != NULL && P->P_R != NULL) //P có đầy đủ 2 cây con
{
//Sẽ tìm nút cực phải của cây con trái làm nút thay thế
Node = P; //Ghi nhớ nút cần xoá
//Chuyển sang nhánh trái để tìm nút "thay thế" và cho P trỏ vào
Q = P;
P = P->P_L;
while(P->P_R != NULL) //Tìm đến nút cực phải
{
Q = P;
P = P->P_R;
}
//Chuyển giá trị trong nút thay thế lên nút cần xoá
Node->KEY = P->KEY;
}
/* Nút cần xoá bây giờ là nút P, nó chỉ có thể là nút lá hoặc có 1 nhánh con. Nếu P có 1 nhánh con thì dùng con trỏ Child trỏ
if(P->P_L != NULL)
{
Child = P->P_L;
}
else
{
Child = P->P_R;
}
if(P == T) //Nếu nút cần xoá là nút gốc của cây
{
T = Child;
}
else //Sửa mối nối cũ trỏ vào P thành trỏ vào Child
{
if(Q->P_L == P)
{
Q->P_L = Child;
}
else
{
Q->P_R = Child;
}
}
free(P); //Giải phóng P
}
Đánh giá
Qua giải thuật trên ta thấy khi loại bỏ 1 nút ra khỏi cây nhị phân tìm kiếm, thì việc sửa lại cây chỉ cần sửa lại 1 mối nối. Như vậy chi phí thời gian cho sửa đổi này cũng không
đáng kể. Nếu cho biết giá trị khoá của 1 nút cần loại bỏ trên cây nhị phân tìm kiếm, thì trước hết ta phải tìm ra nút cần loại bỏ, rồi có thể từ vị trí nút cần loại bỏ tìm tiếp xuống
phía dưới để tìm nút cần thay thế, bởi vậy tương tự như khi tìm kiếm rồi bổ sung, phép tìm kiếm rồi loại bỏ cũng có chi phí trung bình về thời gian ở cấp \(O(log_2n)\).

You might also like