程序内容比较多,本人就捡本人这个问题相关的部分来发代码吧:
数据结构非常简单:
数据结构非常简单:
typedef struct Node{ int num; struct Node *next; }
有一个文本文件,里面装满了随机数,用空格或什么的分隔每一个数,这个本人不管怎么分,总之每次fscanf的都是一个int值就对了。
本人最开始的append是每次都遍历一次链表,好把文件中新增的结构放在表的最后。思路是这样的:
对应的代码如下:
/*追加节点*/ int append(NODE *HEAD,int num) { if (!HEAD || num < 0) { return 0; } /*设置cur = HEAD*/ NODE *cur = HEAD; /*cur一直遍历到最后*/ while (cur->next) { cur = cur->next; } /*设置一个temp保存数据*/ NODE *temp = create_empty(); set_num(temp,num); /*将cur的next指向temp*/ cur->next = temp; return 1; }
其实问题就已经解决了
但是本人发现假如读取超过100万个内容的时候就开始成几何级的费时间了(其实超过10万个数就已经超过2秒了)。
于是本人就想到每次直接在链表尾部增加不久好了么?于是就有了这个思路:
测试用的文件里面只有两个数,分别是7875和17912
满怀信心的F5,结果发现只输出17912……可是应该从head开始的话应该先有7875才对。
实现的代码还有相应做测试的main函数就一并都发来了:
void file_append(NODE *node,int num) { if (!node) { return; } printf("\nbefore_node addr:0x%p\n",&node); NODE *temp = create_empty(); temp->num = num; node->next = temp; /*这样应该保证每次node都是最后一个节点?*/ node = node->next; printf("\n temp addr:0x%p\n node addr:0x%p\n", &temp,&node); } int file_input(NODE *HEAD,const char *filename) { if (!HEAD) { return 0; } NODE *tail = HEAD; while (tail->next) { tail = tail->next; } /*这样一来,tail最终指向了最后一个节点*/ FILE *fp = fopen(filename, "r"); if (!fp) { return 0; } while (!feof(fp)) { int temp; fscanf(fp, "%d", &temp); printf("\n===============%d=================\n",temp); file_append(tail, temp); printf("\nnode(tail) addr:0x%p\n", &tail); printf("\n====================================\n"); } fclose(fp); return 1; } int main(int argc,char *argv[]) { if (argc < 2) { printf("请指明文件名\n"); getchar(); return 1; } NODE *head = create_empty(); clock_t start, end; start = clock(); if(!file_input(head, argv[1])){ printf("文件不存在!\n"); getchar(); return 2; } end = clock(); printf("文件加载完毕!共耗时%d毫秒。\n",end - start); print_chaintab(head); getchar(); remove_all_nodes(head); free(head); return 0; }
运行结果如下:
结果发现每次node地址虽然变了,但都不是temp生成出来的……问一下这是怎么回事?本人的代码到底哪里出现了错误?是逻辑错误?还是本人单纯的不会写?
解决方案
20
20
void file_append(NODE **node,int num) { if (!*node) { return; } printf("\nbefore_node addr:0x%p\n",*node); NODE *temp = create_empty(); temp->num = num; (*node)->next = temp; /*这样应该保证每次node都是最后一个节点?*/ (*node) = temp; printf("\n temp addr:0x%p\n node addr:0x%p\n", *node); } //... file_append(&tail, temp);
5
每次都返回头指针,注意改一下函数的类型
5
每次都返回头指针,注意改一下函数的类型
改函数类型?返回头指针……是这个意思么?
NODE *file_append(NODE **node,int num){ /*............*/ return (*node); }这样改么?问一下这样改的意义是什么?
……………………
迭代么?
不是这样,当然这样做也是可以,相似strcpy一样;可以通过返回值也可以通过传入传出参数实现返回。
这是两种方式来获取链表的头节点:一种是传二重指针进去,第二种就是传一重指针,但是返回值返回头节点地址;当然,还有第三种,就是两个都做,不过没必要。