C 从单个链表的末尾到开头迭代,而不反转它
假设我有一个单链表,其中包含从一个文件中收集的单词,我希望能够从头到尾和从头到尾打印这些单词。第一个选项的执行编码如下:C 从单个链表的末尾到开头迭代,而不反转它,c,list,recursion,C,List,Recursion,假设我有一个单链表,其中包含从一个文件中收集的单词,我希望能够从头到尾和从头到尾打印这些单词。第一个选项的执行编码如下: void writeWords(t_list *lp, FILE *fp, int total_num_words) { t_list *aux; aux = lp; while(aux != NULL){ writeOneWord((t_word*) getItemList(aux), fp, total_num_words);
void writeWords(t_list *lp, FILE *fp, int total_num_words) {
t_list *aux;
aux = lp;
while(aux != NULL){
writeOneWord((t_word*) getItemList(aux), fp, total_num_words);
aux = getNextListElement(aux);
}
}
也就是说,列表按正常顺序迭代,每个节点的内容由writeOneWord
打印
现在,我的疑问是:正如我所说的,我希望能够从列表的末尾到开头进行迭代,同时保持列表的原样,这样就不会出现反转。我知道代码应该对应于某种递归实现,但到目前为止,我一直在尝试这样做,但没有任何效果。有人能解释一下吗?你肯定想要一个递归函数 让函数调用本身传递列表中的下一项,然后在递归调用返回后打印该项。这样,列表的末尾将首先打印
void writeWords(t_list *lp, FILE *fp, int total_num_words) {
if (lp != NULL) {
writeWords(getNextListElement(lp), fp, total_num_words);
writeOneWord((t_word*) getItemList(lp), fp, total_num_words);
}
}
您应该使用双链接列表。但这里有一个解决办法:
void writeWordsBackwards(t_list *lp, FILE *fp, int total_num_words) {
size_t i = 0;
t_list words[total_num_words];
for (size_t i = 0; lp && i < total_num_words; i += 1) {
words[i] = lp;
lp = getNextListElement(lp);
}
while (i >= 0) {
writeOneWord((t_word*) getItemList(words[i]), fp, total_num_words);
i -= 1;
}
}
void writeWordsBackwards(t_list*lp,FILE*fp,int total_num_words){
尺寸i=0;
列出单词[单词总数];
对于(大小i=0;lp&&i=0){
writeOneWord((t_word*)getItemList(单词[i]),fp,总单词数);
i-=1;
}
}
与递归方法不同,它使用更少的堆栈空间。但它仍然需要潜在的无限堆栈空间
malloc
可能更适合于避免堆栈溢出。当然,您意识到,虽然可以这样做,但如果必须这样做,则表明选择的数据结构不正确。您说要保留链表。可以临时修改它吗?如果允许临时修改,则只需恒定的内存开销即可完成(与递归不同)。如果total_num_words
足够大,则很快就会崩溃。堆上有更多的空间,它比我预期的更有效、更直观。谢谢当然,你应该使用堆来实现这一点。因为这个练习特别是关于学习如何递归地实现它,所以我将使用dbush的答案。然而,我确实考虑过这一点,而且您的实现似乎是功能性的和有用的,所以您得到了一个荣誉称号。谢谢