1. Trang chủ
  2. » Công Nghệ Thông Tin

Cây nhị phân và Ứng dụng

63 2 0
Tài liệu đã được kiểm tra trùng lặp

Đ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

Thông tin cơ bản

Tiêu đề Cây Nhị Phân
Tác giả Trần Nguyễn Đắc Lãm, Ngô Duy Thành Long, Hà Minh Khánh, Nguyễn Đình Hoàng, Nguyễn Vũ Khương
Định dạng
Số trang 63
Dung lượng 5,21 MB
File đính kèm Source code.rar (5 MB)

Nội dung

Cây nhị phân và Ứng dụng trong môn Cấu trúc dữ liệu và giải thuật Nội dụng: - Khái niệm, các loại cây nhị phân, tính chất - Biểu diễn cây nhị phân (biểu thức, số học, chữ, ....) bằng mảng, cấu trúc liên kết, các trường hợp suy biến - Trình bày giải thuật bằng mã giả tựa C++, phép tạo cây - tạo nút, duyệt cây - trước - giữa - sau, thêm, sửa, xoá. - Ứng dụng vào các bài toán như biểu diễn biểu thức, cây nhị phân tìm kiếm, BST cân bằng, cây AVL, các kỹ thuật quay lui và thuật giải

Trang 2

CÂY NHỊ PHÂN

Trang 3

Khái niệm: Cây (tree) là 1 tập hợp hữu hạn các nút trong đó có 1 nút đặc

biệt gọi là nút gốc (root) Giữa các nút có 1 quan hệ phân cấp gọi là “quan

hệ cha con”

Định nghĩa đệ quy:

 Một nút là 1 cây Nút đó cũng là gốc của cây đó

 Nếu n là 1 nút và T1, T2, …, Tk là các cây với n1, n2, …, nk lần lượt là các gốc, thì 1 cây mới T sẽ được tạo lập bằng cách cho n trở thành cha của các nút n1, n2, …, nk; nghĩa là n là gốc còn T1, T2, …, Tk là các các

cây con (subtrees) của gốc Lúc đó n1, n2, …, nk là con của nút n

Quy ước: Cây không có nút nào ta gọi là cây rỗng (null tree)

1.KHÁI NIỆM

Trang 4

T2

Trang 5

 Chiều cao (height) hay chiều sâu

(depth) của một cây là số mức lớn

nhất của nút có trên cây

1

2

3

4

Trang 8

Biểu diễn lịch thi đấu

Trang 10

( A / B + C )*( D – E )

*

ED

+

C/

BA

Trang 11

2.1 Khái niệm và tính chất

2.2 Biểu diễn cây nhị phân

2.3 Phép duyệt cây nhị phân

2 CÂY NHỊ PHÂN

Trang 12

2.1 Khái niệm và tính chất

Khái niệm: Cây nhị phân là một dạng quan trọng của cấu trúc cây Mọi nút

trên cây chỉ có tối đa hai nhánh con Với một nút, ta phân biệt cây con trái và cây con phải của cây Cây nhị phân là cây có tính đến thứ tự của các nhánh con

A

B C

A

C B

A

C B

Trang 13

Các cây nhị phân suy biến

3 4

5

Cây zíc-zắc

Trang 14

Các cây nhị phân hoàn chỉnh và đầy đủ

1

3 2

 Cây nhị phân hoàn chỉnh (complete binary tree) : Nếu chiều cao của cây

là h thì mọi nút có mức < h - 1 đều có đúng 2 nút con

 Cây nhị phân đầy đủ (full binary tree) : Mọi nút có mức <= h - 1 đều có đúng 2 nút con

1

3 2

Complete binary tree Full binary tree

Trang 15

2.1 Khái niệm và tính chất

Tính chất:

 Trong các cây nhị phân có cùng số lượng nút thì cây nhị phân suy biến

có chiều cao lớn nhất, cây nhị phân hoàn chỉnh có chiều cao nhỏ nhất

 Số lượng tối đa các nút trên mức i của cây nhị phân là , tối thiểu là 1 (i

Trang 16

2.1 Biểu diễn cây nhị phân

 Biểu diễn bằng mảng

 Biểu diễn bằng cấu trúc liên kết

Trang 17

Biểu diễn bằng mảng

Nếu có một cây nhị phân đầy đủ, ta đánh số các

nút trên cây theo thứ tự từ mức 1 trở đi, hết mức

này đến mức khác từ trái sang phải đối với các nút

3

Trang 18

Biểu diễn bằng mảng

A B

C D

Trường hợp cây nhị phân không đầy đủ:

1 Thêm một số nút giả để được cây nhị

phân đầy đủ và gán những giá trị đặc

biệt cho những nút này

2 Hoặc thêm một mảng phụ để đánh dấu

những nút nào là nút giả mà ta thêm

vào

Trang 19

Biểu diễn bằng mảng

A B

C D

nhớ vì có thể sẽ phải thêm rất nhiều nút

giả thì mới được cây nhị phân đầy đủ

Trang 20

Biểu diễn bằng cấu trúc liên kết

Khi biểu diễn cây nhị phân bằng cấu trúc liên kết, mỗi nút (node) là một bản ghi (record) gồm ba trường:

 Trường Info: chứa giá trị lưu tại nút đó

 Trường Left: Chứa liên kết (con trỏ) trỏ tới cây nhị phân bên trái của node

 Trường Right: Chưa liên kết (con trỏ) trỏ tới cây nhị phân bên phải của node

Nếu một cây nhị phân trống, nó sẽ được biểu diễn thành con trỏ NULL

Trang 21

Biểu diễn bằng cấu trúc liên kết

Cấu trúc node của cây:

Khai báo node bằng cấu trúc liên kết (con trỏ):

struct Tnode {

    char word [ 20 ];

    struct Tnode * left ;

    struct Tnode * right ;

Trang 22

Biểu diễn bằng cấu trúc liên kết

A

E

Đối với cây ta chỉ cần quan

tâm giữ lại nút gốc (root), bởi

từ nút gốc, đi theo các hướng

liên kết left, right ta có thể

duyệt được mọi nút khác

Trang 23

MakeNodeNode* makeNode( char * word ){

// Phân bổ( bộ nhớ cho nút mới

    Node * newNode = NULL ;

    newNode = ( Node *)malloc( sizeof ( Node ));

// Kiể( m tra câ2 p phát bộ nhớ có thành cổng

        newNode -> left = NULL ;

        newNode -> right = NULL ;

        strcpy( newNode -> word , word );

    }

    return newNode ;// Tra ( lại con tro ( để2 n địa chỉ ( cu (a nút mới }

Trang 24

InsertNode * Insert( Node * tree ){

    char word [ 20 ] = "a" ;

//Nể2 u word == "~" thì khổng nhập nút tiể2 p theo

    if (strcmp( word , "~" )== 0 ) return NULL ;

    tree =  makeTreeNode( word );

    printf( "Input left child of %s : " , word );

    tree -> left = Insert( tree -> left );

    printf( "Input right child of %s : " , word );

    tree -> right =Insert( tree -> right );

    return tree ;      

}

Trang 25

Tính số nút và chiều cao của cây

// Hàm tính sổ2 lượng nút cu (a cây

int countNodes( Node * tree ) {

    if ( tree == NULL ) return 0 ;

    else {

        int ld = countNodes( tree -> left );

        int rd = countNodes( tree -> right );

        return 1 + ld + rd ;

    }

}

// Hàm tính chiểI u cao hay độ sâu cu (a cây

int depth( Node * tree ) {

    if ( tree == NULL ) return 0 ;

    int ld = depth( tree -> left );

    int rd = depth( tree -> right );

    return 1 + ( ld > rd ? ld : rd );

}

1

3 2

Trang 26

Loại bỏ cây

void freeTree( Node * tree )

{

    if ( tree == NULL ) return ;

// Loại bo ( cây bển trái

    freeTree( tree -> left );

// Loại bo ( cây bển pha (i

    freeTree( tree -> right );

Trang 27

Phép duyệt cây

Định nghĩa: Phép xử lý các nút trên cây mà ta gọi chung là phép thăm

(Visit) các nút một cách hệ thống sao cho mỗi nút chỉ được thăm một lần gọi là phép duyệt cây

 Nếu 1 nút không có nút con trái (hoặc phải) thì liên kết Left (Right) của nút đó được liên kết tới 1 nút đặc biệt là NULL

 Nếu cây rỗng thì nút gốc của cây đó được gán bằng NULL

Trang 28

Phép duyệt cây

Thứ tự trước (Preorder) NLR

‑ Thăm nút (Visit a node)

‑ Thăm cây con trái theo thứ tự trước (Visit left subtree)

‑ Thăm cây con phải theo thứ tự trước (Visit right subtree)

Thứ tự giữa (Inorder) LNR

‑ Thăm cây con trái theo thứ tự trước (Visit left subtree)

‑ Thăm nút (Visit a node)

‑ Thăm cây con phải theo thứ tự trước (Visit right subtree)

Thứ tự sau (Postorder) LRN

‑ Thăm cây con trái theo thứ tự trước (Visit left subtree)

‑ Thăm cây con phải theo thứ tự trước (Visit right subtree)

‑ Thăm nút (Visit a node)

Trang 32

Nhận xét

Ta thấy tổ chức cây theo cấu trúc liên kết tỏ ra thích hợp hơn cách tổ chức bằng mảng 1 chiều

Tuy nhiên, cũng có những nhược điểm:

 Tốc độ xử lý chậm hơn do chỉ có nút gốc của cây có thể được truy cập trực tiếp còn các nút khác chỉ được truy cập sau khi đã qua 1 số thao tác duyệt cây

 Tốn bộ nhớ hơn do ngoài trường info phải có thêm trường left và right

ở mỗi nút để lưu trữ địa chỉ nút con trái và nút con phải của nút đó

Trang 33

3.1 Cây biểu diễn biểu thức (Expression Tree) 3.2 Cây nhị phân tìm kiếm (Binary Search Tree) 3.3 Cây BST cân bằng hoàn toàn

3.4 Cây AVL (Adelson-Velsky và Landis)

3.ỨNG DỤNG

Trang 34

Cây biểu diễn biểu thức

 Cây biểu thức là một cây nhị phân, trong

đó mỗi nút nhánh tương ứng với toán tử

và mỗi nút lá tương ứng với toán hạng

+

3 /

2 10

Trang 35

Cây biểu diễn biểu thức

Bước 1: Input biểu thức trung tố, chuẩn hoá trung tố và chuyển sang hậu tố

(LRN)

Bước 2: Khởi tạo một Stack rỗng dùng để chứa các nút của cây

Bước 3: Đọc lần lượt các phần tử của biểu thức LRN từ trái qua phải, với mỗi

phần tử đó:

 Tạo ra một nút mới newNode chứa phần tử mới đọc được

 Nếu phần tử này là toán tử, lấy từ Stack ra hai nút ( theo thứ tự x và y), sau đó đem liên kết phải của newNode trỏ đến x, đem liên kết trái của newNode trỏ đến y

 Đẩy newNode vào Stack

Bước 4: Sau khi kết thúc bước 2 thì toàn bộ biểu thức được đọc xong, trong Stack

chỉ còn duy nhất một phần tử, phần tử đó chính là gốc của cây nhị phân biểu diễn biểu thức

Trang 36

Xây dựng cây biểu diễn biểu thức

Bước 1:

Biểu thức LNR: (2+3)/5

Biểu thức LRN: 2 3 + 5 /

Đọc Xử lý stack exp

2 Input “2” vào chuỗi exp ( 2

+ “+” có priority ≥ “(“ ở đỉnh Stack, đẩy “+” vào Stack (+ 2

3 Input “3” vào chuỗi exp (+ 2 3

/ Stack đang rỗng, đẩy “/” vào Stack / 2 3 +

5 Input “5” vào chuỗi exp / 2 3 + 5

Hết Pop các phần tử còn lại trong Stack đưa vào chuỗi exp 2 3 + 5 /

Trang 37

5 /

Các bước còn lại:

Trang 38

Xây dựng cây biểu diễn biểu thức

void buildExpTree <Biể( u thức exp> {

Trang 39

Tính toán cây biễu diễn biểu thức

double evaluationNode( Node * root ){

    if ( root == NULL ) return 0 ;

    // Nể2 u root là nút lá, return vểI giá trị kiể( u double

    if ( root -> left == NULL && root -> right == NULL )

    return ( double )atof( root -> data );

    // Tính cây con bển trái

    double leftval = EvaluationNode( root -> left );

    // Tính cây con bển pha (i

    double rightval = EvaluationNode( root -> right );

    // Kiể( m tra toán tư( rổI i tính toán

    if (* root -> data == '+' ) return leftval + rightval ;

    if (* root -> data == '-' ) return leftval - rightval ;

    if (* root -> data == '*' ) return leftval * rightval ;

    if (* root -> data == '/' ) return leftval / rightval ;     return pow( leftval , rightval );

}

Trang 40

Độ phức tạp tính toán của evaluationNode

Cách 1: Vì tính toán giá trị biểu thức, ta phải

duyệt qua tất cả các node, mỗi node một lần

(Tương tự các phép duyệt cây)

Vậy độ phức tạp tính toán là:

+

3 2

/

5 /

Trang 41

Độ phức tạp tính toán của evaluationNode

Trang 42

Độ phức tạp tính toán của evaluationNode

Tính giá trị của cây, ta phải tính giá trị của cây con bên trái (left child) và cây con bên phải(right child):

 double leftval = EvaluationNode( root -> left );

 double rightval = EvaluationNode( root -> right );

Ta có n-1 node trừ root đã xét

Giả sử trường hợp trung bình: Left child có (n-1)/2 nút con ,Right child có (n-1)/2 nút con

Vậy ,

Dễ thấy với thoả mản

Vậy theo định lý Master

Trang 43

3.2 Cây nhị phân tìm kiếm

Khái niệm: Cây tìm kiếm nhị phân(Binary Search Tree, viết

tắt: BST) là một cây nhị phân và có thêm các ràng buộc sau đây:

1 Giá trị của tất cả các Node ở cây con bên trái <= giá trị của Node

Trang 44

10 3

7 4

8

10 3

7 2

3.2 Cây nhị phân tìm kiếm

Trang 45

3.2 Cây nhị phân tìm kiếm

Cây tìm kiếm nhị phân là một cấu trúc dữ liệu hiệu quả cho phép chúng

ta xây dựng nên một danh sách mà dữ liệu trên đó được sắp xếp:

 Nó được gọi là cây tìm kiếm nhị phân vì nó có thể được sử dụng để tìm kiếm sự hiện diện của một phần tử trong thời gian O(log (n))

 Trong trường hợp xấu nhất, cây có thể bị suy biến thành một danh sách liên kết đơn với các thao tác có độ phức tạp O(n)

Kết luận: Để có độ phức tạp giải thuật luôn là O(lg(n)) cần có cải tiến

cấu trúc của cây BST: cây nhị phân tìm kiếm cân bằng hoàn toàn, cây AVL,

Trang 46

3.3 BST cân bằng hoàn toàn

Khái niệm: Cây nhị phân tìm kiếm cân bằng hoàn toàn là cây nhị

phân tìm kiếm (BST) mà tại mỗi nút của nó, số nút của cây con trái

chênh lệch không quá 1 so với số nút của cây con phải

Đánh giá:

 Nếu cây cân đối thì việc tìm kiếm sẽ nhanh

 Đối với cây cân bằng hoàn toàn có N nút, trong trường hợp xấu nhất chỉ phải tìm qua log2N phần tử

Trang 47

10 3

3.3 BST cân bằng hoàn toàn

8

10 4

7 3

1

9

Trang 48

3.3 BST cân bằng hoàn toàn

Nếu thêm khóa 11 vào cây BST

thì cây không còn cân bằng hoàn

Trang 50

3.4 Cây AVL

Khái niệm: Cây nhị phân tìm kiếm cân bằng (AVL) là cây BST mà

tại mỗi nút của nó độ cao của cây con trái và của cây con phải chênh lệch không quá 1

Binary Search Tree AVL Tree

Trang 51

Xây dựng AVL Tree

Để xây dựng được cây AVL thì các bạn nắm rõ các yếu

tố sau:

Trang 52

Khái niệm “chiều cao”

(4)

Tính chiều cao qua hàm đệ quy:

int getHeight( Node* root ) {

    if ( root == NULL )

        return 0 ;

    return 1 + max(getHeight( root

-> left ), getHeight( root -> right ));

}

Chiều cao của một Node chính là số

các node trên một đường dẫn dài

nhất từ Node đó đến Node = NULL

Và quy ước Node = NULL có chiều

cao bằng 0

Trang 53

Các kỹ thuật quay cây AVL

1 Kỹ thuật quay phải (áp dụng cho cây lệch trái)

2 Kỹ thuật quay trái (áp dụng cho cây lệch phải)

Trang 54

1 Kỹ thuật quay phải

Cập nhật lại chiều cao:

height (root) = 1 + max (1, 1) = 2 height (X) = 1 + max (root, 2) = 3

(3)

(2)

Trang 55

Node* rightRotate( Node* root ){

    Node * x = root -> left ;

 

    // Bắ2 t đâI u quay pha (i

    root -> left = x -> right ;

    x -> right = root ;

 

    // Thiể2 t lập chiểI u cao

    root -> height = 1 + max(getHeight( root -> left ),

getHeight( root -> right ));

    x -> height = 1 + max(getHeight( x -> left ), getHeight( x

Trang 56

2 Kỹ thuật quay trái

Y.left = root Cập nhật lại chiều cao:

height (root) = 1 + max (1, 1) = 2 height (Y) = 1 + max (root, 2) = 3

(2)

(3)

Trang 57

Node* leftRotate( Node* root ) {

    Node * y = root -> right ;

 

    // Bắ2 t đâI u quay trái

    root -> right = y -> left ;

    y -> left = root ;

 

    // Thiể2 t lập chiểI u cao

    root -> height = 1 + max(getHeight( root -> left ),

getHeight( root -> right ));

    y -> height = 1 + max(getHeight( y -> left ), getHeight( y

Trang 58

Các trường hợp cây bị lệch

1 Trường hợp trái trái – left left

2 Trường hợp trái phải – left right

3 Trường hợp phải phải – right right

4 Trường hợp phải trái – right left

Trang 59

1 Trường hợp trái trái – left left

Có thể thấy rằng height(X) – height(Y) = 2 => cây bị lệch sang bên trái

value(Vàng) < value(X) => Node vàng nằm bên trái => “Trái trái”.

Xảy ra khi: height(X) – height(Y) > 1 và value(Vàng) < value(X)

Xử lý: quay phải Node root – rotateRight(root)

Trang 60

2 Trường hợp trái phải – left right

Cây đã bị lệch sang bên trái Node vàng nằm bên phải so với Node X

19

23 AVL Tree

Left left case

Xảy ra khi: height(X) – height(Y) > 1 và value(Vàng) > value(X)

Xử lý: rotateLeft(X) => rotateRight(root)

Trang 61

3 Trường hợp phải phải – right right

Trang 62

4 Trường hợp phải trái – right left

Cây đã bị lệch sang bên phải Node vàng nằm bên trái so với Node Y

rotateRight(Y) rotateLeft(root)

Xảy ra khi: height(X) – height(Y) < -1 và value(Vàng) < value(Y)

Xử lý: rotateRight(Y) -> rotateLeft(root)

Trang 63

Thank you

for watching!

Ngày đăng: 11/06/2024, 10:27

TỪ KHÓA LIÊN QUAN

w