我经常在 C 语言中使用线性链表结构
typedef struct _node {
...node guts...
struct _node *next
} node;
以及枚举惯用法
for (node *each = headNode; each != NULL; each = each->next)
我现在所处的情况是,循环列表对我很有吸引力(例如,最后一个节点的下一个节点设置为 headNode)。天真地,我以为我会使用类似于 for
表达式的东西,而且我盯着它看的越多,我想我已经说服自己你不能用循环链表。
看来,无论我为结束条件想出什么样的表达式,我都会遇到一个基本问题,即我希望所述条件在第一次遇到同一节点时评估为 true,而在第二次遇到相同节点时评估为 false。我可以做一些有循环副作用的事情:
for (BOOL traversed = FALSE, node *each = headNode;
traversed && each != headNode;
traversed = TRUE, each = each->next)
但这肯定会失去空终止列表方法的优雅/简单性。这么晚了,是不是有什么逻辑诡计让我无法理解?
显然我可以使用 while() 构造,也许这是唯一的方法。
最佳答案
假设如下:
- 空列表意味着起点为 NULL。
- 最后一个节点将是
next
指针引用您的起点的节点,包括next
指针自引用的单节点列表。 - NO
next
指针为 NULL。
然后下面将使用第三级表达式作为增量步骤来执行您想要的操作。
// node* start comes from "somewhere'
for (node *p=start; p; p = (p->next==start ? NULL : p->next))
{
// do something with p
}
注意:无论怎样,当退出时,p
将为 NULL; start
将保持不变,并且 NULL start
是可以接受的,就像单自引用节点一样。
也就是说,我会使用 while 循环来完成此操作,但由于您专门要求使用 for 循环,所以您得到了 =P。
关于c - 如何使用 for() 表达式枚举循环链表?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13831162/