Bài giảng Cấu trúc dữ liệu và giải thuật – Bài 21: Cây nhị phân tìm kiếm thông tin đến các bạn những kiến thức về khái niệm cây nhị phân tìm kiếm, các thao tác trên cây nhị phân tìm kiếm, một vài ví dụ sử dụng cây nhị phân tìm kiếm.
Trang 1Gi ảng viên: TS Ngo Huu Phuc
Tel: 0438 326 077 Mob: 098 5696 580 Email: ngohuuphuc76@gmail.com
Trang 2Bài 21: Cây nh ị phân tìm kiếm
21.1 Khái ni ệm cây nhị phân tìm kiếm.
21.2 Các thao tác trên cây nh ị phân tìm kiếm.
21.3 M ột vài ví dụ sử dụng cây nhị phân tìm kiếm.
Tham kh ảo :
1 Deshpande Kakde: C and Data structures.chm, Chapter 20: Linked Lists
2 Elliz Horowitz – Fundamentals of Data Structures.chm, Chapter 4: Linked Lists
3 Kyle Loudon: Mastering Algorithms with C.chm, Chapter 5 Linked Lists.
4 Bài gi ảng TS Nguyễn Nam Hồng
Trang 321.1 Khái ni ệm về cây nhị phân tìm kiếm (1/4)
Cây nh ị phân tìm kiếm là cây rỗng hoặc cây mà node có
ch ứa các khóa
Các khóa c ủa node trên cây con bên trái nhỏ hơn khóa của
root, khóa c ủa các node trên cây con bên phải lớn hơn khóa
c ủa root
Cây con bên trái và ph ải cũng là cây nhị phân tìm kiếm.
Vi ệc quản lý cây nhị phân thông qua node root.
Trang 421.1 Khái ni ệm về cây NPTK (2/4)
Ví d ụ về cây nhị phân tìm kiếm
50 30
35
60
70
65
Trang 521.1 Khái ni ệm về cây NPTK (3/4)
Cây nh ị phân tìm kiếm là t ập con c ủa cây nhị phân, nên nó
c ũng có các cách duyệt LNR, LRN, NLR
V ới cây nhị phân tìm kiếm, nếu duyệt cây theo kiểu inorder ta
s ẽ được một dãy đã sắp theo chiều tăng dần.
Cây nh ị phân tìm kiếm là cấu trúc tìm kiếm hiệu quả Việc tìm
ki ếm trên cây nhị phân tìm kiếm nhanh hơn tìm kiếm tuần tự Tuy nhiên, vi ệc biểu diễn cây dạng mảng sẽ gây khó khăn cho
vi ệc thêm, bớt
V ới việc biểu diễn dạng liên kết, ta có độ phức tạp của việc tìm
ki ếm là O( logn).
Trang 621.1 Khái ni ệm về cây NPTK (4/4)
template < class TreeEntry>
struct tbnode {
TreeEntry data;
struct tbnode *lchild, *rchild;
};
Trang 721.2 Các thao tác trên cây NPTK (1/)
M ột số thao tác trên cây nhị phân tìm kiếm:
Trang 821.2 Các thao tác trên cây NPTK (2/)
Khai báo l ớp cây nhị phân tìm kiếm:
template <class TreeEntry> class TBTree {
public:
TBTree();
int TBInsert(TreeEntry value);
int TBCount();
voidTBRInorder(tbnode<TreeEntry>* treenode, QueueClassC<TreeEntry> *q);
voidTBRPostorder(tbnode<TreeEntry>* treenode, QueueClassC<TreeEntry> *q);
voidTBRPreorder(tbnode<TreeEntry>* treenode, QueueClassC<TreeEntry> *q);
voidTBInorder(QueueClassC<TreeEntry>* q);
voidTBPostorder(QueueClassC<TreeEntry>* q);
voidTBPreorder(QueueClassC<TreeEntry>* q);
voidTBLevelorder(QueueClassC<TreeEntry>* q);
voidTBGetptr(tbnode<TreeEntry> **father, tbnode<TreeEntry> **curr, TreeEntry value);
int TBDelete(TreeEntry value);
template<typename TreeEntry> friend void TreePrint(TBTree<TreeEntry> tree, int type);
private: tbnode<TreeEntry> * root; };
Trang 921.2 Các thao tác trên cây NPTK (3/)
Kh ởi tạo cây NPTK:
template < class TreeEntry>
TBTree<TreeEntry>::TBTree()
{
root=NULL;
}
root NULL
Trang 1021.2 Các thao tác trên cây NPTK (4/)
Thêm m ột node vào cây NPTK:
N ếu cây rỗng, cấp phát ô nhớ cho con
tr ỏ root
N ếu cây không rỗng:
S ử dụng 2 con trỏ temp và temp1 để
xác định vị trí cần thêm (con trỏ temp1
s ẽ trỏ vào NULL , con tr ỏ temp sẽ trỏ
vào node là cha c ủa node mới ).
Tùy thu ộc vào giá trị mới được thêm
vào s ẽ cấp phát ô nhớ cho temp->left
hay temp->right
root
50
NULL NULL
1
2
50 30
35
60
70 65
Thêm node
có giá tr ị
45 vào cây
temp
45
NULL NULL NULL
Trang 1121.2 Các thao tác trên cây NPTK (5/)
template <class TreeEntry>
int TBTree<TreeEntry>::TBInsert(TreeEntry value)
{ int kt=0;
tbnode<TreeEntry> * temp, *temp1;
if(root==NULL) {
root = (tbnode<TreeEntry> *)
malloc(sizeof(tbnode<TreeEntry>));
if (root==NULL) {
printf("Khong du bo nho");
return kt; } kt=1;
root->data=value;
root->lchild=root->rchild=NULL;
}
else
{ temp1=root;
while(temp1!=NULL) {
temp=temp1;
Thêm m ột node vào cây NPTK elsetemp1=temp1->lchild;
temp1=temp1->rchild; } if(temp->data>value) { temp->lchild = (tbnode<TreeEntry> *)
malloc(sizeof(tbnode<TreeEntry>)); if(temp->lchild==NULL) {
printf("Khong du bo nho");
return kt; } kt=1;
temp=temp->lchild;
temp->data=value;
temp->lchild=temp->rchild=NULL;
} else { temp->rchild = (tbnode<TreeEntry> *)
malloc(sizeof(tbnode<TreeEntry>)); if(temp->rchild==NULL) {
printf("Khong du bo nho");
return kt; } kt=1;
temp=temp->rchild;
temp->data=value;
temp->lchild=temp->rchild=NULL; }
Trang 1221.2 Các thao tác trên cây NPTK (6/)
Xóa node không có con
Trang 1321.2 Các thao tác trên cây NPTK (7/)
Trang 1421.2 Các thao tác trên cây NPTK (8/)
Xóa node có 2 con