Xây dựng cây nhị phân biểu thức

Một phần của tài liệu BAI_7_TREE_HUONGDANHOC (Trang 32 - 40)

Các biểu thức toán học đều có thể được thể hiện dưới dạng cấu trúc cây, trong đó các nút lá là các toán hạng và các nút còn lại là các toán tử.

Cây biểu thức được tạo bởi các nút vì vậy trước tiên phải xây dựng cấu trúc của một nút để biểu diễn cây biểu thức. Mỗi một nút gồm ba thành phần: giá trị

(value), nhánh con trái (LeftChild) và nhánh con phải (RightChild). struct BinaryTreeNode

{

String value;

Struct BinaryTreeNode *LeftChild; Struct BinaryTreeNode *RightChild;

};

a. Tạo cây biểu thức từ dạng Tiền tố (prefix) và Hậu tố (postfix)

Các chuỗi tiền tố và hậu tố không chứa các dấu ngoặc đơn nên việc xây dựng cây nhị phân biểu thức tương ứng rất dễ dàng, các bước thực hiện tương tự như tính toán giá trị của biểu thức.

Thuật toán được thực hiện như sau:

Chuẩn bị một Stack rỗng. Lặp qua lại từng phần tử trong chuỗi hậu tố

- Tạo ra một đối tượng nút kiểu BinaryTreeNode (nút của cây biểu thức) chứa giá trị của phần tử được xét,

- Nếu phần tử được xét đến là toán hạng thì đẩy vào một Stack, - Nếu phần tử được xét là toán tử thì:

+ Lấy ra một phần tử toán hạng từ Stack và đặt làm nhánh con phải của nút được tạo (RightChild ),

+ Lấy tiếp ra phần tử toán hạng tiếp theo từ Stack và đặt làm nhánh con trái của nút được tạo (LeftChild),

+ Sau đó đẩy nút vừa tạo vào Stack.

Quá trình lặp liên tục kết thúc và phần tử cuối cùng còn lại trong Stack chính là nút gốc của cây biểu thức.

Ví dụ 0.22 Cho biểu thức dưới dạng hậu tố: 2 3 4 * 5 6 / - +

Xây dựng cây biểu thức tương ứng.

Đọc Mô tả Cây biểu thức

+ Tạo nút chứa dấu “+” - Tạo nút chứa dấu “-” và là con phải của dấu “+”

/ Tạo nút chứa dấu “/” và là con phải của dấu “ - ” 6 Tạo nút chứa số “6” và làm con phải của dấu “/” 5 Tạo nút chứa số “5” và làm con trái của dấu “/”

* Tạo nút chứa “*” và làm con trái của “-” 4 Tạo nút chứa “4” và làm con phải của “*” 3 Tạo nút chứa “3” và làm con trái của “*”

2

Tạo nút chứa “2” và làm con trái của “+”

b. Tạo cây biểu thức từ dạng trung tố (Infix)

Thông thường khi ta có một biểu thức thì biểu thức thường được cho dưới dạng trung tố vì vậy sẽ hợp lý hơn nếu ta có thể tạo được cây biểu thức trực tiếp từ biểu thức trung tố. Tuy nhiên chi phí để tạo cây biểu thức từ dạng trung tố sẽ cao hơn nhiều so với từ dạng hậu tố và trung tố vì phải tiến hành xử lý các dấu ngoặc đơn. Chính vì vậy phương pháp xây dựng cây biểu thức từ dạng trung tố thường là sự kết hợp giữa hai thuật toán chuyển đổi sang dạng hậu tố từ dạng trung tố và tạo cây biểu thức cùng lúc.

Để thực hiện thuật toán này cần sử dụng hai Stack là: - Stack OperatorStrack để chứa các toán tử của biểu thức,

- Stack NodeStack để chứa các nút tạo nên cấu trúc cây, nút gốc của các cây con được xây dựng từ dưới lên).

Trước khi thực hiện thuật toán ta phải xây dựng một phương thức (hàm)

CreateSubTree có nhiệm vụ tạo một cây biểu thức gồm 3 nút, với nút gốc là toán tử lấy từ OperatorStack ra, hai nút lá là toán hạng lần lượt lấy từ

NodeStack ra. Cuối cùng đưa nút gốc vào lại NodeStack.

Các bước thực hiện thuật toán:

Lần lượt duyệt qua từng phần tử trong biểu thức trung tố

- Nếu gặp được toán hạng thì đẩy phần tử đọc được vào trong NodeStack,

- Nếu gặp được dấu mở ngoặc “(“ thì đẩy vào trong OperatorStack,

- Nếu gặp được dấu đóng ngoặc “)” thì

+ Lặp liên tục cho đến khi lấy được dấu ngoặc “(“ trong ngăn xếp

+ Lấy dấu mở ngoặc ra khỏi OperatorStack,

- Nếu gặp toán tử:

+ Lặp cho đến khi OperatorStack rỗng hoặc độ ưu tiên của toán tử ở đỉnh OpeatorStack nhỏ hơn độ ưu tiên của toán tử hiện đại. Mỗi lần lặp

gọi phương thức CreateSubTree,

+ Đẩy toán tử đọc được vào OpeatorStack,

Khi hết vòng lặp nếu OperatorStack còn phần tử thì gọi phương thức

CreateSubTree cho đến khi OperatorStack rỗng.

Nút cuối cùng nằm trong NodeStack là nút gốc của cây.

Ví dụ 0.23 Chuyển biểu thức (a+b) * c - d/e thành cây biểu thức

Đọc Mô tả OperatorStack NodeStack

( Đẩy “(“ vào OperatorStack ( {Rỗng}

a Đẩy “a” vào NodeStack ( a

+ Đẩy “+” và OperatorStack (, + a

b Đẩy “b” vào trong NodeStack (, + a, b ) Lấy “a”, “b” ra tạo thành hai nút con

của nút “+”. Sau đó đẩy nút “+” vào NodeStack {rỗng} + * Đẩy “*” vào OperatorStack * + c Đẩy “c” vào NodeStack * +, c - Lấy “+” và “c” tạo thành hai nút con của “*”. Sau đó đẩy “*” vào NodeStack và đẩy “-” vào OperatorStack - * d Đẩy “d” vào NodeStack - *, d / Đẩy “/” vào OperatorStack -, / *, d e Đẩy “e” vào NodeStack -, / *, d, e

Kết thúc vòng lặp -, / *, d, e

Cho “d” và “e” thành nút con của “/”. Sau đó đẩy “/” vào NodeStack

Cho “*” và “/” làm nút con của “-”. Sau đó đẩy “-” vào NodeStack

{rỗng} -

Như vậy cuối cùng còn lại nút “-” ở trong NodeStack, đây chính là nút gốc của cây biểu thức cần tạo.

Ví dụ 0.24 Xây dựng cây biểu thức từ biểu thức (a + b) * c – d/e Biểu thức dạng hậu tố tương ứng: a, b, +, c,*, d, e, /, -

Đọc Kết quả cây nhị phân biểu thức được tạo a

b

+

c

d

e

/

Một phần của tài liệu BAI_7_TREE_HUONGDANHOC (Trang 32 - 40)

Tải bản đầy đủ (PDF)

(42 trang)