列表的每个节点都使用数据保存后续节点的地址。这就是为什么递归运行良好的原因,如下例所示:它需要输入,例如123456
,然后将其打印为列表6 -> 5 -> 4 -> 3 -> 2 -> 1 -> NULL.
/* Structure types ----------------------------------------------*/
typedef int data;
struct list_element {
int data;
struct list_element *next;
};
typedef struct list_element ELEM;
typedef ELEM *LINK;
/* Recursive list create and list print---------------*/
LINK create_list(int n) {
if (n == 0) {
return NULL;
}
else {
LINK head = (LINK) malloc(sizeof(ELEM));
head -> data = n % 10;
head -> next = create_list(n / 10);
return head;
}
}
void print_list(LINK head) {
if(head == NULL)
printf("NULL\n");
else {
printf("%d -> ", head -> data);
print_list(head -> next);
}
}
/* MAIN ---------------------------------------------------------*/
int main(int argc, char *argv[]) {
int n; LINK ls;
printf("\nType an integer:\n");
scanf("%d", &n);
ls = create_list(n);
print_list(ls);
return 0;
}
节点不包含其上一个邻居的地址。从这个考虑问题:
如何才能从 last 节点打印列表,才能拥有NULL -> 6 -> 5 -> 4 -> 3 -> 2 -> 1
?
问题Reversing a linkedlist recursively in c的答案实际上指出了一个稍微不同的问题。他们的目标是扭转名单本身。我的目标不是改变列表中数据的顺序。
答案 0 :(得分:5)
您可以通过更改打印调用的顺序来执行此操作。如果您先打印列表的其余部分,那么订单将被反转。
@ECHO OFF
这是一个关于如何浏览列表的问题。
答案 1 :(得分:2)
您只需要交换printf语句和递归调用。
void print_list(LINK head){
if(head == NULL)
printf("NULL\n");
else{
print_list(head -> next);
printf("%d -> ", head -> data);
}
}
然后将执行最后一次递归调用中的printf语句,然后执行其他语句。
答案 2 :(得分:2)
当你的列表变得非常大时,递归将无助于你最终运行我们的堆栈空间。
如果是要求,您可以反向打印列表,则必须调整数据结构(和算法)以实现的要求,而无需耗尽堆栈空间。
简而言之,您必须实现双向链接列表,即不仅有next
成员,还有prev
成员。
答案 3 :(得分:1)
将printf语句推送到堆栈时,只需遍历最后一个节点。一旦你到达列表的末尾,堆栈将开始展开,你的打印功能将被调用。
void print_list_reverse(LINK head){
if(head == NULL)
printf("NULL -> ");
else{
print_list_reverse(head -> next);
printf("%d -> ", head -> data);
}
}