red black tree

18 1.1K 18
red black  tree

Đang tải... (xem toàn văn)

Tài liệu hạn chế xem trước, để xem đầy đủ mời bạn chọn Tải xuống

Thông tin tài liệu

Cây đỏ đen là 1 loại cây thông dụng trong nhiều lĩnh vực,đây là bài tập lớn môn cấu trúc dữ liệu của mình,nếu bạn nào muốn lấy code thì liên hệ vs mình mình gửi,

TRƯỜNG ĐẠI HỌC BÁCH KHOA HÀ NỘI Viện Công nghệ Thông tin và Truyền thông BÀI TẬP LỚN MÔN HỌC CẤU TRÚC DỮ LIỆU VÀ GIẢI THUẬT Đề tài: "Red-Black Tree" Sinh viên thực hiện: Phùng Văn Chiến. SHSV:20111253 Mã lớp: Giáo viên hướng dẫn: PGS Nguyễn Đức Nghĩa HÀ NỘI – 2013 Mục lục I.Định nghĩa 3 A.Giới Thiệu: 3 B.Cây đỏ đen 3 1.Đinh nghĩa: 3 2.Các tính chất của cây đỏ đen: 3 3.Chiều cao đen 4 4.Các định lí: 4 5.Khai báo cấu trúc 5 6.Các phép toán trên cây đỏ-đen 5 II.Cài đặt 5 1.Khởi tạo 5 2.Tạo một nút mới 6 3.Các phép quay 6 4.Phép chèn(insertation) 7 5.Phép xóa(Deletation) 11 6.Tìm Kiếm(Search): 15 III.Ứng Dụng 16 I.Định nghĩa A.Giới Thiệu: Cây tìm kiếm nhị phân là một cấu trúc lưu trữ dữ liệu tốt với tốc độ tìm kiếm nhanh. Tuy nhiên trong một số trường hợp cây tìm kiếm nhị phân có một số hạn chế. Nó hoạt động tốt nếu dữ liệu được chèn vào cây theo thứ tự ngẫu nhiên. Tuy nhiên, nếu dữ liệu được chèn vào theo thứ tự đã đuợc sắp xếp sẽ không hiệu quả. Khi các trị số cần chèn đã đuợc sắp xếp thì cây nhị phân trở nên không cân bằng. Khi cây không cân bằng, nó mất đi khả năng tìm kiếm nhanh (hoặc chèn hoặc xóa) một phần tử đã cho. Chúng ta khảo sát một cách giải quyết vấn đề của cây không cân bằng: đó là cây đỏ đen, là cây tìm kiếm nhị phân có thêm một vài đặc điểm. B.Cây đỏ đen 1.Đinh nghĩa: Cây đỏ-đen là một dạng cây tìm kiếm nhị phân tự cân bằng ,một cấu trúc dữ liệu được sử dụng trong khoa học máy tính.Cấu trúc ban đầu của nó được đưa ra vào năm 1972 bởi Rudolf Bayer. Ông gọi chúng là “B-cây cân bằng”, còn tên hiện nay được đưa ra năm 1978 bởi Leo J. Guibas và Robert Sedgewick.Nó là cấu trúc phức tạp nhưng cho kết quả tốt về thời gian trong trường hợp xấu nhất. .Các phép toán trên chúng như tìm kiếm (search), chèn (insert), và xóa (delete) trong thời gian O(logn), trong đó n là số các phần tử của cây . 2.Các tính chất của cây đỏ đen: Tc1:Một nút hoặc là đỏ hoặc là đen. Tc2:Gốc là đen. Tc3:Tất cả các lá là đen. Tc4:Cả hai con của mọi nút đỏ là đen. (và suy ra mọi nút đỏ có nút cha là đen.) Tc5:Tất cả các đường đi từ một nút đã cho tới các lá chứa một số như nhau các nút đen. Tính chất 5 còn được gọi là tính chất "cân bằng đen". Số các nút đen trên một đường đi từ gôc tới mỗi lá được gọi là độ dài đen của đường đi đó. Sức mạnh của cây đỏ đen nằm trong các tính chất trên. Từ các tính chất này suy ra trong các đường đi từ gốc tới các lá đường đi dài nhất không vượt quá hai lần đường đi ngắn nhất. Do đó cây đỏ đen là gần cân bằng. Vì các thuật toán chèn, xóa, tìm kiếm trong trường hợp xấu nhất đều tỷ lệ với chiều cao của cây nên cây đỏ đen rất hiệu quả trong các trường hợp xấu nhất,không giống như cây tìm kiếm nhị phân thông thường . Trong nhiều biểu diễn của dữ liệu cây, có thể có các nút chỉ có một con và có các lá có chứa dữ liệu. Tuy nhiên có thể biểu diễn cây đỏ đen ta có một chút thay đổi mà không làm thay đổi tính chất cơ bản của cây và Thời Gian Tính của các thuật toán. Với mục đích này, ta đưa thêm các lá null vào làm con phải hoặc con trái hoặc cả hai của những nút không có chúng, các lá này không chứa dữ liệu mà chỉ làm nhiệm vụ thông báo rằng tại đây cây đã kết thúc, như hình vẽ ở dưới. Việc thêm các nút này làm cho tất cả các nút trong của cây đều chứa dữ liệu và có hai con, hay khác đi cây đỏ đen cùng với các lá null là cây nhị phân đầy dủ. Khi đó số các "lá null" nhiều hơn số các nút chứa dữ liệu của cây một lá. Hình 1: Ví dụ về cây đỏ-đen 3.Chiều cao đen Chiều cao đen (Black -Height) của một nút P bằng số nút đen trên đường dẫn từ nút đó đến nút lá bất kì (không tính các nút von trỏ Null).Kí hiệu là bh(P).Ví dụ như hình vẽ trên có bh(root)=2. 4.Các định lí: Định lí 1:Một cây đỏ-đen bất kì có nút gốc là x có ít nhất n=2 bh(x) - 1 nút trong,bh(x) là chiều cao đen của gốc x. Chứng minh:Ta chứng minh bằng quy nạp với 1 nút x bất kì(x không nhất thiết là nút gốc màu đen,ở đây ta tổng quát cho cả trường hợp x là nút đỏ hay x là con của 1 nút gốc khác) +) Nếu bh=0 thì x=NULL,do đó số nút trong =0=2 bh(x) - 1. +) Nếu bh=1 thì x<> NULL,số nút trong ít nhất là 1=2 bh(x) - 1. +)Giả sử các cây có chiều cao đen =bh(x)-1 đều thỏa mãn định lí.Xét cây gốc x có chiều cao đen bh(x),khi đó 2 con của nó có chiều cao đen hoặc =bh(x)-1(nếu x đen) hoặc =bh(x) (nếu x đỏ).Do đó số nút tối thiểu của cây gốc x bằng số nút trên 2 cây con cộng 1. (2 bh(x)-1 - 1)+(2 bh(x)-1 - 1)=2 bh(x) - 1. ==> ĐPCM. Định lí 2:Trong một cây đỏ đen,ít nhất một nửa số nút trên đường dẫn từ gốc đến lá là nút đen. => Chứng minh dựa vào tính chất 4(mọi nút đỏ đều có 2 con là nút đen do đó không có 2 nút đỏ kề nhau trên đường đi từ gốc đến là). Định lí 3:Một cây đỏ-đen có n nút trong có chiều cao h<=2log(n+1). Chứng minh : Gọi h là chiều cao cây đỏ-đen gốc x. Theo định lí 2 ta có bh(x)>=h/2. Mặt khác từ định lí 1 ta có n>=2 bh(x) - 1>=2 h/2 -1. Do đó h<=2log(n+1). ==> ĐPCM. 5.Khai báo cấu trúc typedef int Data; /* Kiểu dữ liệu khoá */ typedef enum { BLACK, RED } nodeColor; typedef struct Node { nodeColor color; /* Màu node (BLACK, RED) */ Data info; /* Khoá sử dụng tìm kiếm */ struct Node *left; /* Con trái */ struct Node *right; /* Con phải */ struct Node *parent; /* Cha */ }; typedef struct Node pNode typedef struct RedBlackTree{pNode **root}; struct RedBlackTree Tree; 6.Các phép toán trên cây đỏ-đen -init(item):Khởi tạo cây có gốc có khóa là item. - makeRedBlack(value,node):tạo 1 nút với khóa cho bởi value,và có nút cha là nút node. - rotate_left(RedBlack),rotate_right(RedBlack): quay trái quay phải nút RedBlack. - insert(item):chèn nút với khóa cho bởi item vào cây đỏ-đen ; - delete(item):xóa nút cho bởi khóa item trong cây đỏ-đen; - search(item):tìm nút với khóa item trong cây đỏ-đen; II.Cài đặt 1.Khởi tạo. pNode * init(Data item) { Tree.root=(pNode *)malloc(sizeof(pNode *)); Tree.root->info=item; Tree.root->color=BLACK; Tree.root->left=NULL; Tree->right=NULL; Tree->parent=NULL; return Tree.root; } 2.Tạo một nút mới. Input:phần tử cần tạo; Các bước: +) Cấp phát bộ nhớ cho nút mới. +)Kiểm tra lỗi cấp phát; +) Nếu cấp phát được thì đưa phần tử vào nút mới và gán nó màu đỏ (mặc định); +)Con trái con phải gán bằng NULL. OutPut:Con trỏ tới địa chỉ nút mới. pNode *makeRedBlack(Data x,pNode *node) { pNode * newRedBlack=NULL; newRedBlack=(pNode *)malloc( sizeof( pNode *)); //khởi tạo if(newRedBlack==NULL) { printf(”Out of memmory”) exit(1); } else { newRedBlack->info=x; newRedBlack->color=RED; newRedBlack->left=NULL; newRedBlack->right=NULL; newRedBlack->parent=node; } return newRedBlack; } .Thời Gian Tính: Dễ thấy Thời Gian Tính của thao tác là O(1). 3.Các phép quay Thực ra quay không có nghĩa là các node bị quay mà để chỉ sự thay đổi quan hệ giữa chúng. Một node được chọn làm "đỉnh" của phép quay. Nếu chúng ta đang thực hiện một phép quay qua phải, node "đỉnh" này sẽ di chuyển xuống dưới và về bên phải, vào vị trí của node con bên phải của nó. Node con bên trái sẽ đi lên để chiếm lấy vị trí của nó. hình 2:quay trái,quay phải Phải đảm bảo trong phép quay phải, node ở đỉnh phải có node con trái. Nếu không chẳng có gì để quay vào điểm đỉnh. Tương tự, nếu làm phép quay trái, node ở đỉnh phải có node con phải. a.Quay trái void rotate_left(pNode * x) { pNode * y=x->right;// set node x->right=y->left;//con phải của x được gán bằng con trái của y if(y->left!=NULL) y->left->parent=x;//cha của nút con trái của y giờ là x y->parent=x->parent;//gán cha cho y là cha của x if(x->parent==NULL) //x là nút gốc { T.root =y; //thì y giờ thành nút gốc. } else if(x==x->parent->left) //Trái lại thì gán cha của x cho cha y. { x->parent->left=y; } else x->parent->right=y; y->left=x; //đặt lại con trái cho node và cha của RedBlack; x->parent=y; } b.Quay phải void rotate_right(pNode * x) { pNode * y=x->left;// set y x->left=y->right;//con trái của x được gán bằng con phải của y if(y->right!=NULL) y->right->parent=x;//cha của nút con phải của y giờ là x y->parent=x->parent;//gán cha cho y là cha của x if(x->parent==NULL) { T.root=y;//x là nút gốc thì y giờ thành nút gốc. } else if(x==x->parent->left) //Trái lại thì gán cha của x cho cha y. { x->parent->left=y; } else x->parent->right=y; y->right=x; //đặt lại con phải cho y và cha của x; x->parent=y; } .Thời Gian Tính:Các thao tác quay đều có Thời Gian Tính là hằng số :O(1). 4.Phép chèn(insertation) -Phép chèn bắt đầu bằng việc bổ sung một nút như trong cây tìm kiếm nhị phân bình thường và gán cho nó màu đỏ.Ta xem xét để bảo toàn tính chất đỏ đen từ các nút lân cận với nút mới bổ xung.Thuật ngữ nút chú bác sẽ dùng để chỉ nút anh(hoặc em) với nút cha của nút đó như trong cây phả hệ.Chú ý: .Tính chất 3(Tất cả các lá đều đen-là các nút NULL) giữ nguyên. .Tính chất 4(Cả 2 con của nút đỏ là đen) nếu bị thay vì thêm một nút đỏ có thể gán màu đen cho 1 nút đỏ hoặc thực hiện phép quay. .Tính chất 5(Tất cả các đường đi từ gốc tới các lá có cùng một số nút đen) nếu bị thay đổi vì việc thêm 1 nút đỏ có thể gán 1 nút đỏ thành đen hoặc thực hiện phép quay. -Khi chèn cần chú ý các trường hợp sau(giả sử X trỏ đến nút vừa thêm): CASE 1:X là nút gốc,đổi màu X thành đen;(được thực hiện trong hàm makeRedBlack() ) CASE 2: Cả 2 nút: cha và chú đều đỏ thì thực hiện đổi mầu nút cha, chú thành đen, màu nút ông thành đỏ, X trỏ đến nút ông, tiếp tục kiểm tra X tại vị trí mới. hình 3:minh họa thao tác CASE 3 :Nút cha đỏ, chú đen. Nút cha và nút X không cùng là con trái hoặc phải. Thực hiện đổi mầu nút ông thành đỏ, X –đen, quay trái(phải) nút cha, quay phải(trái) nút ông. Hình 4:minh họa thao tác trên (nút cha quay trái,nút ông quay phải) CASE 4: Nút cha đỏ, chú đen. X và nút cha hoặc cùng là con trái hoặc cùng là con phải. Thực hiện đổi màu nút cha thành đen, ông thành đỏ, quay phải nút ông. hình 5:minh họa thao tác trên. a.Hàm sau minh họa thao tác chèn khóa có giá trị item vào cây đỏ-đen được trỏ bởi con trỏ RedBlack; void insert(Data item) { pNode * x=Tree.root; pNode * y=x->parent; while(x!=NULL) { if(item<x->info) { y=x; x=x->left; } else if(item>x->info) { y=x; x=x->right; } x=makeRedBlack(item,y); changecolor(x);//thao tác đổi màu theo nguyên tắc trên } Trong chương trình chính để chèn khóa key ta gọi insert(T.root,key). b.Hàm xác định nút chú bác và nút ông: pNode * grandparent(pNode * RedBlack) { return RedBlack->parent->parent; } pNode * uncle(pNode * RedBlack) { pNode * tmp; tmp=grandparent(RedBlack); if(RedBlack->parent==tmp->left) return tmp->right; else return tmp->left; } c. Hàm đổi màu:changecolor(RedBlack) {đổi màu theo các nguyên tắc đã nêu ở trên} void changecolor(pNode * RedBlack) { pNode * grandpt; pNode * ule; grandpt=grandparent(RedBlack); ule=uncle(RedBlack); if(RedBlack->parent==NULL) //case 1 { RedBlack->color=BLACK; } else if(RedBlack->parent->color==RED&&ule->color==RED) //case 2 { RedBlack->parent->color=BLACK; ule->color=BLACK; grandpt->color=RED; changecolor(T,grandpt); } else if(RedBlack->parent->color==RED&&(ule->color==BLACK|| ule==NULL)) { if(RedBlack->parent==grandpt->left&&RedBlack==RedBlack->parent->right) //case 3 { grandpt->color=RED; RedBlack->color=BLACK; rotate_left(T,RedBlack->parent);//quay trái; rotate_right(T,grandpt);//quay phải; } else if(RedBlack->parent==grandpt->right&&RedBlack==RedBlack->parent->left) //case 3 { grandpt->color=RED; RedBlack->color=BLACK; rotate_right(T,RedBlack->parent);//quay trái; rotate_left(T,grandpt);//quay phải; } else if(RedBlack->parent==grandpt->left&&RedBlack==RedBlack->parent->left) //case 4 { RedBlack->parent->color=BLACK; grandpt->color=RED; rotate_right(T,grandpt); [...]...} else if(RedBlack->parent==grandpt->right&&RedBlack==RedBlack->parent->right) //case 4 { RedBlack->parent->color =BLACK; grandpt->color =RED; rotate_left(T,grandpt); } } } Thời Gian Tính: - Do cây đỏ đen là cây cân bằng nên nếu duyệt theo chiều cao của cây thì luôn có thời gian là O(logn) - Hàm changecolor(RedBlack) có thời gian là O(logn) trong trường hợp 1(đi... while(x! =Tree. root&&x->color= =BLACK) { if(x==x->parent->left) { w=x->parent->right; if(w!=NULL) { if(w->color= =RED) { w->color =BLACK; x->parent->color =RED; rotate_left(x->parent); //case 1 //case 1 //case 1 w=x->parent->right; //case 1 } if(w->left!=NULL&&w->right!=NULL) { if(w->left->color= =BLACK& &w->right->color= =BLACK) { w->color =RED; //case2 x=x->parent; //case2 } else { if(w->right->color =BLACK) ... { if(w->right->color =BLACK) { w->left->color =BLACK; //case 3 w->color =RED; //case 3 rotate_right(w); //case 3 w=x->parent->right; //case 3 } w->color=x->parent->color; //case 4 x->parent->color =BLACK; //case 4 w->right->color =BLACK; //case 4 rotate_left(x->parent); //case 4 x =Tree. root; } } } } else (Trường hợp x là con phải thực hiện tương tự) x->color =BLACK; } Thời Gian Tính: -Tìm nút thay thế có... chỉ cha mới của N, SL chỉ con trái của S, và SR chỉ con phải của S (chúng tồn tại vì S không thể là lá) Hàm xóa nút có khóa là k: void deleteRedBlack(Data k) { pNode *x,*y,*z; pNode *Null=null(); if (Tree. root==NULL) { printf("\ncay rong khong the xoa"); return; } z =Tree. root; while(z!=NULL&&z->info!=k) { if(z->info>k)z=z->left; else z=z->right; } if(z==NULL) { printf("khong tim thay nut nao co khoa =... y=z; else y=find_min(z->right); if(y->left!=NULL) x=y->left; else x=y->right; if(x==NULL) x=Null; x->parent=y->parent; if(y->parent==NULL) Tree. root=x; else if(y==y->parent->left) y->parent->left=x; else y->parent->right=x; if(y!=z) z->info=y->info; if(y->color= =BLACK) deletefix(x); y->left=y->right=Null; free(y); printf("\n xoa thanh cong"); } Nếu cả N và gốc ban đầu của nó là đen thì sau khi xóa các... tồi nhất.Ta thấy rõ điều này vì theo định lí 3 ta có : Một cây đỏ đen có n nút có chiều cao hinfo!=key||x!=NULL) { if(x->info>key) x=x->left; else x=x->right; } return x; } Thời Gian Tính: -Cũng giống như các cây nhị phân khác,thời gian tìm kiếm trung bình là O(logn).Tuy nhiên . newRedBlack->info=x; newRedBlack->color =RED; newRedBlack->left=NULL; newRedBlack->right=NULL; newRedBlack->parent=node; } return newRedBlack; . grandparent(pNode * RedBlack) { return RedBlack->parent->parent; } pNode * uncle(pNode * RedBlack) { pNode * tmp; tmp=grandparent(RedBlack); if(RedBlack->parent==tmp->left)

Ngày đăng: 14/02/2014, 21:35

Hình ảnh liên quan

Hình 1: Ví dụ về cây đỏ-đen - red black  tree

Hình 1.

Ví dụ về cây đỏ-đen Xem tại trang 4 của tài liệu.
hình 3:minh họa thao tác - red black  tree

hình 3.

minh họa thao tác Xem tại trang 8 của tài liệu.
Hình 4:minh họa thao tác trên - red black  tree

Hình 4.

minh họa thao tác trên Xem tại trang 8 của tài liệu.
hình 5:minh họa thao tác trên. - red black  tree

hình 5.

minh họa thao tác trên Xem tại trang 9 của tài liệu.

Mục lục

    2.Các tính chất của cây đỏ đen:

    5.Khai báo cấu trúc

    6.Các phép toán trên cây đỏ-đen

Tài liệu cùng người dùng

  • Đang cập nhật ...

Tài liệu liên quan