- Cho một cây nhị phân với cấu trúc đỉnh như sau:
struct BTNode { int data; BTNode* left; BTNode* right; }viết hàm
void foo(BTNode* root)nhận vào con trỏ đến gốc cây và in ra các node trên cây theo thứ tự inorder mà chỉ được dùngO(1)-không gian. (Do đó, các loại giải pháp dùng recursion hay dùng stack là không được phép.) - Tiếp theo câu trước, giả sử cây nhị phân cho trước là cây tìm kiếm nhị phân: data bên trái nhỏ hơn gốc và nhỏ hơn data bên phải. Viết hàm
BTNode* bar(BTNode* root), sắp xếp lại các con trỏ, để biến cây nhị phân này thành một danh sách liên kết kép và vòng lặp (circular doubly-linked list). Hàm trả về con trỏ vào phần tử đầu của danh sách. Ở đây, ta sẽ hiểuleftlà con trỏ về phần tử trước (previous) vàrighttrả về phần tử sau (next) trong danh sách liên kết kép.
Thông điệp ngắn
- No public Twitter messages.
Phản hồi mới
- Administrator on Làm an toàn thông tin thì học gì?
- Metallica on Làm an toàn thông tin thì học gì?
- Huân on Làm an toàn thông tin thì học gì?
- HaThuyAnh on Gõ ký hiệu Toán
- HaThuyAnh on Gõ ký hiệu Toán
- HaThuyAnh on Gõ ký hiệu Toán
- HaThuyAnh on Gõ ký hiệu Toán
- Ha on Kinh Dịch và Data Mining
- Ha on Logic bậc nhất và truy vấn hội
- Lee on Gỡ rối tơ lòng
- NQH on Phân tích khảo sát góp ý dự thảo Hiến Pháp bằng Bổ Đề Johnson-Lindenstrauss
- duccuong on Cây nhị phân và cây tìm kiếm nhị phân
- thanhnt_hcmus on Logic bậc nhất và truy vấn hội
- NQH on Logic bậc nhất và truy vấn hội
- thanhnt_hcmus on Logic bậc nhất và truy vấn hội
-
Bài mới
- Học Thế Nào
- “Không quản lý được về an ninh”
- Phân tích khảo sát góp ý dự thảo Hiến Pháp bằng Bổ Đề Johnson-Lindenstrauss
- Giải thưởng Turing 2012
- Những toilet không cửa hay là tại sao phải biết thiết kế
- Tây tiến cùng Hiến pháp
- All the lonely people/ where do they all come from
- Thơ Nguyễn Đắc Kiên
- Bốn thế giới ảo và một thế giới thực…
- Kích thước tối đa của mảng 1 chiều dùng C/C++
Chuyên Mục
- Âm Nhạc (61)
- Ảnh hưởng của CNTT (6)
- Ảo giác (3)
- Bảo mật và mật mã học (82)
- Biển Đông (7)
- Blog cầu (5)
- Bơi (7)
- C++ (6)
- Các hệ thống máy tính (9)
- Các hội nghị KHMT (12)
- Công nghệ phần mềm (6)
- Cấu trúc dữ liệu (6)
- Chính trị trong ngành (30)
- Chưa phân loại (52)
- CNTT các nước và VN (47)
- Combinatorics (24)
- Cơ sở dữ liệu (9)
- Danh ngôn (13)
- Dành cho du học sinh (111)
- Games (2)
- Giáo dục (87)
- Giới thiệu sách (38)
- KHMT và Kinh Tế (1)
- KHMT và luật pháp (6)
- KHMT và sinh học (6)
- KHMT và triết học (3)
- Lập trình (22)
- Lịch Sử (1)
- Lịch sử Việt Nam (3)
- Lý thuyết mã hóa (6)
- Lý thuyết tính toán (57)
- Lý thuyết thông tin (17)
- Logic (2)
- Mạng máy tính (36)
- Mỹ quốc (12)
- Nghiên cứu nghiên kiếc (50)
- Nhân vật và sự kiện (133)
- Python (2)
- Quả đất của ta (1)
- Siêu Nhiên (1)
- Thông báo (31)
- Thần kinh học (1)
- Thầy bói nói mò (1)
- Thuật ngữ chuyên ngành (8)
- Thuật Toán (69)
- Thơ (7)
- Tin tức đó đây (106)
- Toán Ứng Dụng (13)
- Toán tối ưu (5)
- Trang web hay (31)
- Trí tuệ nhân tạo (52)
- Vui – Giải Trí (276)
- Vượt định kiến (26)
- Xác suất & thống kê (71)
- Xuất bản (14)
- Y Học (2)
Kho bài
Báo chí
Bảo mật
Blog Việt
- Bùi Nguyên Cẩm Ly
- Giáp Văn Dương
- Hoàng Hoài Minh
- Huy Đức
- Lê Hồng Giang
- Minh Biện
- Ngô Bảo Châu
- Nguyễn Ngọc Tư
- Nguyễn Tiến Dũng
- Nguyễn Đình Đăng
- Nhiệt Huyết
- Phạm Thị Hoài
- Quỹ Trí Tuệ Việt Nam
- Talawas
- Tin Khó Tin
- Toe Loe
- Trang Hạ
- Trần Hữu Dũng
- Trần Vinh Dự
- Vũ Hà Văn
- Vũ Hoàng Linh
- Đàm Thanh Sơn
- Đông A
- Đỗ Quốc Anh
- Đoàn Kết
Chưa phân loại
Giáo dục
Kỹ thuật
Khoa học khác
Kinh tế, luật pháp, xã hội
- A Tiny Revolution
- Andrew Sullivan.com
- Chicago’s Law Faculty
- Computing Chris
- Creative Capitalism
- Crooked Timber
- Daily Kos
- Freakonomics
- Free exchange
- Furdlog
- Instapundit
- Marginal Revolution
- Social Science Statistics
- Structured Procrastination
- The Becker-Posner Blog
- The Volokh Conspiracy
- Vietnam Quant. Society
- Đỗ Quốc Anh
Lý thuyết & thuật toán
- Algorithmic Game Theory
- Combinatorics and More
- Comp. Complexity Blog
- CS Theory Overflow
- ECCC
- Ernie’s 3D Pancakes
- Glob of Thoughts
- Godel's Lost Letter
- In Theory
- Luca Trevisan
- Machine Learning (Theory)
- My Biased Coin
- My slice of pizza
- Rudy’s Blog
- Sariel’s Blog
- Shtetl-Optimized
- tcs math
- The Geomblog
- The Quantum Pontiff
- Theory Matters
Mạng
Não học
Toán học
Vật Lý

3 Comments
Hello a NQH,
Em nghĩ bài này mình dùng cách duyệt cây theo giải thuật Moris Traversal, trong quá trình duyệt mình sẽ thay đổi tree, duyệt xong sẽ chuyển ngược về tree ban đầu. Ý tưởng chính là như sau:
1. Initialize current as root
2. While current is not NULL
If current does not have left child
a) Print current’s data
b) Go to the right, i.e., current = current->right
Else
a) Make current as right child of the rightmost node in current’s left subtree
b) Go to this left child, i.e., current = current->left
Theo cách này thì ko yêu cầu thêm về bộ nhớ là hằng số (constant space).
Em copy đoạn C++ code người # viết mọi người kiểm tra xem:
#include #include /* A binary tree tNode has data, pointer to left child and a pointer to right child */ struct tNode { int data; struct tNode* left; struct tNode* right; }; /* Function to traverse binary tree without recursion and without stack */ void MorrisTraversal(struct tNode *root) { struct tNode *current,*pre; if(root == NULL) return; current = root; while(current != NULL) { if(current->left == NULL) { printf(" %d ", current->data); current = current->right; } else { /* Find the inorder predecessor of current */ pre = current->left; while(pre->right != NULL && pre->right != current) pre = pre->right; /* Make current as right child of its inorder predecessor */ if(pre->right == NULL) { pre->right = current; current = current->left; } /* Revert the changes made in if part to restore the original tree i.e., fix the right child of predecssor */ else { pre->right = NULL; printf(" %d ",current->data); current = current->right; } /* End of if condition pre->right == NULL */ } /* End of if condition current->left == NULL*/ } /* End of while */ } /* UTILITY FUNCTIONS */ /* Helper function that allocates a new tNode with the given data and NULL left and right pointers. */ struct tNode* newtNode(int data) { struct tNode* tNode = (struct tNode*) malloc(sizeof(struct tNode)); tNode->data = data; tNode->left = NULL; tNode->right = NULL; return(tNode); } /* Driver program to test above functions*/ int main() { /* Constructed binary tree is 1 / \ 2 3 / \ 4 5 */ struct tNode *root = newtNode(1); root->left = newtNode(2); root->right = newtNode(3); root->left->left = newtNode(4); root->left->right = newtNode(5); MorrisTraversal(root); getchar(); return 0; }Dear bạn Chấn Ngô,
Mình thử check lời giải của bạn. Bạn in ra kết quả theo thứ tự trước Preorder trong khi yêu cầu bài toán là Inorder.
Bản kiểm tra lại xem.
Ý tưởng của mình để in theo thứ tự Inorder dùng O(1)-memory.
1. Initialize current as root
2. While current is not NULL
2.1. Print current’s data.
2.2. If current->left is NULL then current = current->right.
Else
{
2.2.1. Make the right child of the rightmost node in current->left is current->right.
2.2.2. current = current->left.
}
#include
#include
/* A binary tree tNode has data, pointer to left child
and a pointer to right child */
struct tNode
{
int data;
struct tNode* left;
struct tNode* right;
};
void Inorder(struct tNode *root)
{
struct tNode *current,*node;
current = root;
while(current != NULL)
{
printf(” %d “, current->data);
if(current->left == NULL)
{
current = current->right;
}
else
{
/* Find the rightmost node of current->left */
node = current->left;
while(node->right != NULL)
node = node->right;
/* Set the right child of the rightmost node of current->left is current->right*/
node->right = current->right;
current = current->left;
}
} /* End of while */
}
/* UTILITY FUNCTIONS */
/* Helper function that allocates a new tNode with the
given data and NULL left and right pointers. */
struct tNode* newtNode(int data)
{
struct tNode* tNode = (struct tNode*)
malloc(sizeof(struct tNode));
tNode->data = data;
tNode->left = NULL;
tNode->right = NULL;
return(tNode);
}
/* Driver program to test above functions*/
int main()
{
/* Constructed binary tree is
1
/ \
2 3
/ \
4 5
*/
struct tNode *root = newtNode(1);
root->left = newtNode(2);
root->right = newtNode(3);
root->left->left = newtNode(4);
root->left->right = newtNode(5);
Inorder(root);
getchar();
return 0;
}
Hi GS. Hưng
Bài 111 em nghĩ có thể giải dựa trên ý tưởng sau:
- Về cơ bản thì ta dùng một con trỏ đi tuần tự ở nút gốc rồi rẽ sang trái cho tới khi chạm nút lá thì print data -> đi ngược lên nút cha -> print data -> rẽ phải …
- Để giải quyết yêu càu không gian là O(1) thì ta có một con trỏ để duyện trong cây và một biến đi kèm để biết là con trỏ đó đã rẽ phải / trái mấy lần. Biến đó được cập nhật dựa trên cơ chế là:
– Nếu con trỏ ở root thì foo = 1
– Một lần rẽ trái thì foo = foo * 2
– Một lần rẽ phải thì foo = foo * 2 + 1
Với cách này, khi con trỏ chạy tới nút lá, ta gán nó trở về nút gốc và duyệt lại cho tới nút cha của nút cuối cùng mà nó đã trỏ tới. Việc này time-consuming nhưng có thể thỏa mãn yêu cầu về bộ nhớ?