如果您想避免堆栈溢出的可能性,您也可以通过添加队列来使用迭代而不是递归 - 尽管这会使用更多的堆内存,并且仍然存在耗尽的风险如果您有一个大列表或者如果您在内存受限的系统上运行,则使用堆内存。重要的部分是末尾的print_list 函数;其他东西只是我提供的(大部分)自我管理队列实现:
typedef struct node_queue NodeQueue;
struct node_queue {
NODE *n;
NodeQueue *next;
};
/*
* Add an item to the end of the queue.
*
* If the item could not be added, 0 is returned.
* Otherwise, a nonzero value is returned.
*/
int enqueue(NodeQueue **headp, NodeQueue **endp, NODE *n)
{
NodeQueue *old_end = *endp;
NodeQueue *new_end;
new_end = malloc(sizeof *new_end);
if (new_end == NULL) {
return 0;
}
new_end->n = n;
new_end->next = NULL;
if (old_end != NULL) {
old_end->next = new_end;
}
if (*headp == NULL) {
*headp = new_end;
}
*endp = new_end;
return 1;
}
/*
* Remove an item from the head of the queue,
* storing it in the object that "nret" points to.
*
* If no item is in the queue, 0 is returned.
* Otherwise, a nonzero value is returned.
*/
int dequeue(NodeQueue **headp, NodeQueue **endp, NODE **nret)
{
NodeQueue *old_head = *headp;
NodeQueue *new_head;
if (old_head == NULL) {
return 0;
}
if (nret != NULL) {
*nret = old_head->n;
}
new_head = old_head->next;
free(old_head);
if (new_head == NULL) {
*endp = NULL;
}
*headp = new_head;
return 1;
}
void print_list(NODE *start)
{
NodeQueue *head = NULL;
NodeQueue *end = NULL;
NODE *current;
current = start;
/* Iterate all `pNext` nodes, then pop each `pDown` node and repeat. */
for (;;) {
/* Add the "down" node to the node queue. */
if (current->pDown != NULL) {
if (!enqueue(&head, &end, current->pDown)) {
perror("warning: could not add node to queue");
}
}
printf("%s", current->pszNode);
/*
* Move to the "next" node.
* If there is no next node, get the first "down" node from the queue.
* If there is no "down" node, break the loop to end processing.
*/
current = current->pNext;
if (current == NULL) {
if (!dequeue(&head, &end, ¤t)) {
break;
}
}
}
}
这将遍历所有 pNext 项目,然后再移动到 pDown 项目。以下二维列表将打印为A B C D E F G H I J K L M N O P Q:
A
|
B--C
|
D--E-----------F
| |
G-----H I-----J
| | | |
K--L M--N O P
|
Q
您可以在print_list 函数中通过交换pNext 和pDown 来反转pDown/pNext 的优先级,因此pNext 项被添加到队列中,pDown 项被添加到队列中迭代直到用尽,这会将项目的打印顺序更改为A B D C E G K F I O H M Q L J P N,除非您更改列表的结构。
您可以在https://repl.it/NjyV/1 看到同时使用上面的代码和上面的第一个示例二维链表的示例,尽管我更改了NODE 的定义以使使用其字段的代码更简单一些。