[Программирование, Алгоритмы, Go, Интервью] Algorithms in Go: Iterative Postorder Traversal
Автор
Сообщение
news_bot ®
Стаж: 6 лет 9 месяцев
Сообщений: 27286
In this article, we discuss the postorder traversal of a binary tree. What does postorder traversal mean? It means that at first, we process the left subtree of the node, then the right subtree of the node, and only after that we process the node itself.
Why would we need to do it in this order? This approach solves an entire class of algorithmic problems related to the binary trees. For example, to find the longest path between two nodes we need to traverse the tree in a postorder manner. In general, postorder traversal is needed when we cannot process the node without processing its children first. In this manner, for example, we can calculate the height of the tree. To know the height of a node, we need to calculate the height of its children and increment it by one.Let's start with a recursive approach. We need to process the left child, then the right child and finally we can process the node itself. For simplicity, let's just save the values into slice out.
var out []int
var f func(root *TreeNode)
f = func(root *TreeNode) {
if root == nil {
return
}
f(root.Left)
f(root.Right)
out = append(out, root.Val)
}
In this case, the recursive function pretty much embodies the definition of the postorder traversal. We deal with the left subtree, then the right subtree and finally process the root value. Now, how can we convert this function into an iterative version? We can solve this problem with the following approach:
- Push the root node into the stack.
- Push the left child into the stack.
- Pop the left child from the stack and process it.
- Push the right child into the stack.
- Pop the right child from the stack and process it
- Pop the root node and process it.
Let's consider the following tree:
We push the root node 1into the stack. At the next step, we put its left child 2 into the stack.
At the next iteration, we have node 2 at the top of the stack, therefore we try to put its left child into the stack. As the left child is not present, we skip this step and push its right child 4 into the stack.
After this stage, we have three nodes in our stack. The top node 4 does not have any children, so we process its value and pop it from the stack.
Now, we have the same nodes in the stack as at the previous step. However, we have already processed all children of the node 2, therefore we can process node 2 and pop it from the stack.After this iteration, we have a single node in the stack which is node 1. We haven't processed its right child yet, so we put it into the stack. We proceed in the same manner and process the right subtree of node 1.How can we encode this algorithm? We need to have some check that ensures that we don't process a node twice. When we process a node, there are two possible situations:
- We just met this node and need to push its children into the stack.
- We have already processed its children and now are returning back to process the node itself.
We can save the last processed node into the variable prev. If the right child of the current node is equal to prev it means that we already processed both of its children and now need to process the value of the current node. For the left child, we need to check one more condition: it is possible that the current node doesn't have the right child. In this case, we need to check whether prev node is equal to the left child. If that's the case, then we already processed the left child of the current node and we don't have the right child at all, therefore we can process the value of the current node. Let's encode this algorithm in Go
var out []int
prev := root
stack := []*TreeNode{root}
for len(stack) > 0 {
node := stack[len(stack)-1]
if node.Left != nil && node.Left != prev && node.Right != prev {
stack = append(stack, node.Left)
} else if node.Right != nil && node.Right != prev {
stack = append(stack, node.Right)
} else {
prev = node
stack = stack[:len(stack)-1]
out = append(out, node.Val)
}
}
return out
===========
Источник:
habr.com
===========
Похожие новости:
- [Киберпанк, Научно-популярное, Социальные сети и сообщества, Будущее здесь] Что делать, если технический прогресс ухудшает жизнь людей? Перестаньте кормить зверя
- [Информационная безопасность, Google Chrome, API, Браузеры] Внедрение со стороны Google API FLoC вместо Cookie может только повысить уровень слежки за пользователям
- [.NET, C#, ООП, Промышленное программирование] Lazy Properties Are Good. That Is How You Are to Use Them
- [Программирование, Совершенный код, C++, Отладка, C] Как подключить содержимое любых файлов для использования в коде C / C++
- [Алгоритмы, ООП] Вычисление динамических объектов по вектору
- [JavaScript, Программирование, HTML, TensorFlow] Отслеживание лиц в реальном времени в браузере с использованием TensorFlow.js. Часть 6 (перевод)
- [Венчурные инвестиции, Развитие стартапа, Финансы в IT, IT-компании] Новости IT и венчурных инвестиций: новые налоги в России и Франции, кредитка от VK
- [Разработка веб-сайтов, Программирование, ООП] Можно ли пингвина наследовать от птицы?
- [Информационная безопасность, Системное администрирование, GitHub, Софт, IT-компании] Microsoft запустила информационный портал об уязвимости ProxyLogon и опубликовала скрипт для проверки серверов Exchange
- [Программирование, Бизнес-модели, Криптовалюты] Продажа твиттов без NFT и СМС
Теги для поиска: #_programmirovanie (Программирование), #_algoritmy (Алгоритмы), #_go, #_intervju (Интервью), #_go, #_programming, #_programming_challenges, #_interview, #_algorithms, #_programmirovanie (
Программирование
), #_algoritmy (
Алгоритмы
), #_go, #_intervju (
Интервью
)
Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете голосовать в опросах
Вы не можете прикреплять файлы к сообщениям
Вы не можете скачивать файлы
Текущее время: 22-Ноя 08:38
Часовой пояс: UTC + 5
Автор | Сообщение |
---|---|
news_bot ®
Стаж: 6 лет 9 месяцев |
|
In this article, we discuss the postorder traversal of a binary tree. What does postorder traversal mean? It means that at first, we process the left subtree of the node, then the right subtree of the node, and only after that we process the node itself. Why would we need to do it in this order? This approach solves an entire class of algorithmic problems related to the binary trees. For example, to find the longest path between two nodes we need to traverse the tree in a postorder manner. In general, postorder traversal is needed when we cannot process the node without processing its children first. In this manner, for example, we can calculate the height of the tree. To know the height of a node, we need to calculate the height of its children and increment it by one.Let's start with a recursive approach. We need to process the left child, then the right child and finally we can process the node itself. For simplicity, let's just save the values into slice out. var out []int
var f func(root *TreeNode) f = func(root *TreeNode) { if root == nil { return } f(root.Left) f(root.Right) out = append(out, root.Val) }
We push the root node 1into the stack. At the next step, we put its left child 2 into the stack. At the next iteration, we have node 2 at the top of the stack, therefore we try to put its left child into the stack. As the left child is not present, we skip this step and push its right child 4 into the stack. After this stage, we have three nodes in our stack. The top node 4 does not have any children, so we process its value and pop it from the stack. Now, we have the same nodes in the stack as at the previous step. However, we have already processed all children of the node 2, therefore we can process node 2 and pop it from the stack.After this iteration, we have a single node in the stack which is node 1. We haven't processed its right child yet, so we put it into the stack. We proceed in the same manner and process the right subtree of node 1.How can we encode this algorithm? We need to have some check that ensures that we don't process a node twice. When we process a node, there are two possible situations:
var out []int
prev := root stack := []*TreeNode{root} for len(stack) > 0 { node := stack[len(stack)-1] if node.Left != nil && node.Left != prev && node.Right != prev { stack = append(stack, node.Left) } else if node.Right != nil && node.Right != prev { stack = append(stack, node.Right) } else { prev = node stack = stack[:len(stack)-1] out = append(out, node.Val) } } return out =========== Источник: habr.com =========== Похожие новости:
Программирование ), #_algoritmy ( Алгоритмы ), #_go, #_intervju ( Интервью ) |
|
Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете голосовать в опросах
Вы не можете прикреплять файлы к сообщениям
Вы не можете скачивать файлы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете голосовать в опросах
Вы не можете прикреплять файлы к сообщениям
Вы не можете скачивать файлы
Текущее время: 22-Ноя 08:38
Часовой пояс: UTC + 5