如何遍历具有两个节点的链接节点
How to loop through linked nodes that have two nodes
我想遍历这个节点系统,确保命中每个节点,但我不想使用递归。每个节点实际上有两个链接节点。我不知道这是否被称为双链表还是什么。
节点看起来像
class Node {
private:
Node* next_node_type_a;
Node* next_node_type_b;
}
图
|next_node_type_a| ->
|next_node_type_a| -> |next_node_type_b| ->
|start-node| ->
|next_node_type_b| -> |next_node_type_a| ->
|next_node_type_b| ->
最初我没有看到第二个节点,所以我有
while(node){
DoStuffWithNode(node);
node = node->GetNextNodeTypeA();
}
但是我如何修改它以遍历仍在使用 while 循环的两个节点路径?
下面是一些可以处理的示例代码
// Example program
#include <iostream>
#include <string>
class Node {
public:
Node* node_left;
Node* node_right;
std::string value;
Node();
};
Node::Node(){
node_left = 0;
node_right = 0;
}
int main()
{
Node start;
Node a;
Node b;
Node c;
Node d;
Node e;
Node f;
start.value = "start";
a.value = "a";
b.value = "b";
c.value = "c";
d.value = "d";
e.value = "e";
f.value = "f";
start.node_left = &a;
start.node_right = &b;
a.node_left = &c;
a.node_right = &d;
b.node_left = &e;
b.node_right = &f;
Node *n = &start;
while(n){
std::cout << "New node: " << n->value << std::endl;
n = n->node_left;
}
return 0;
}
编辑:我刚刚意识到这是一棵树。
递归是迭代二叉树的惯用方式,如其他答案所示,但如果您需要迭代解决方案,则可以使用其他数据结构(如std::queue
(迭代遍历所有节点。
这称为广度优先搜索,请务必注意,遍历的顺序将与递归的顺序不同,递归是深度优先搜索的实现。
std::queue<Node*> nodesToVisit;
nodesToVisit.push(&start);
while (nodesToVisit.size())
{
Node* n = nodesToVisit.front();
nodesToVisit.pop();
std::cout << "New node: " << n->value << std::endl;
if (n->node_left)
{
nodesToVisit.push(n->node_left);
}
if (n->node_right)
{
nodesToVisit.push(n->node_right);
}
}
相同的方法也适用于非二叉树,但需要额外的代码来处理循环图,例如跟踪std::set
中所有访问过的节点。
最简单的解决方案是使用递归。由于(平衡(二叉树的深度是O(ln(n))
因此您可以放心地假设您不会获得堆栈溢出。
void apply(Node* n)
{
if (n == nullptr) {
return;
}
DoStuffWithNode(n);
apply(n->node_left);
apply(n->node_right);
}
递归访问每个节点可以做到这一点:以下内容将导致深度优先搜索
std::vector<Node*> BuildList(Node* root) {
vector<Node*> nodes;
if(root) {
nodes.push_back(root);
BuildList(root, nodes);
}
return nodes;
}
void BuildList(Node* node, std::vector<Node*> current) {
if(node->next_node_type_a) {
current.push_back(node->next_node_type_a);
BuildList(node->next_node_type_a, current);
}
if(node->next_node_type_b) {
current.push_back(node->next_node_type_b);
BuildList(node->next_node_type_b, current);
}
}
当然,如果您的节点链接回自身,这可能会失败,因此请考虑将std::vector
换成集合类型
您使用的数据结构是二叉树。要在不递归的情况下遍历二叉树,请使用广度优先方法,该方法涉及使用队列来保存每个节点并对其进行处理。
在 Node 类上添加.discovery值将阻止处理任何 Node 两次。如果要重用此函数,请在处理所有节点后重置此发现的值。仅当您无法保证任何节点指向祖先节点或指向自身时,才需要使用此值。
#include <iostream>
#include <queue>
using namespace std;
void BreadthFirst(Node start) {
Queue<Node> Q;
start.discovered = true;
Q.push(start)
while (!Q.isEmpty()) {
Node n = Q.pop()
cout << n.value << endl;
if (n->next_node_type_a != null) {
if(n->next_node_type_a.discovered == false) {
n->next_node_type_a.discovered = true;
Q.push(n->next_node_type_a);
}
}
if (n->next_node_type_b != null) {
if(n->next_node_type_b.discovered == false) {
n->next_node_type_b.discovered = true;
Q.push(n->next_node_type_b);
}
}
}
}
相关文章:
- 如何使用发送数据包所花费的时间计算两个节点之间的距离?
- 检查两个节点在子节点上是否具有相同状态的更优雅的方法
- 比较两个节点坐标的最佳方法是什么?
- 使用 Dijkstra 算法跟踪两个节点之间的最短路径
- 比较C++中两个BST的节点
- 图问题:找出两个节点是否在每个节点的O(1)时间和O(2)存储中共享同一分支
- 如何在单个链表中交换两个节点的位置,只修改指针
- 如何遍历具有两个节点的链接节点
- 查找树中两个节点之间的最大成本边
- 添加一个节点,并在通用树中的两个给定节点之间找到路径成本,其中c 中的儿童列表
- 难以通过具有两个类和一个 LLL 的头节点
- 查找树(不属于任何特定类型的简单连接树)中两个节点之间的路径
- 两个单链列表共享同一个节点和析构函数两次删除相同的内存
- 为什么不交换两个节点?
- 使用 Dijkstra 算法计算两个节点之间的最短路径
- 链接列表C 类,这两个添加节点实现之间的差异是什么?
- 有没有办法在两个ROS节点之间具有优先级
- 在 C 语言的链表中查找最小的两个节点
- 当两个节点相互指向时,不可避免的内存泄漏
- 如何使用BFS查找两个节点之间的距离