程序内容比较多,本人就捡本人这个问题相关的部分来发代码吧:
数据结构非常简单:
数据结构非常简单:
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一样;可以通过返回值也可以通过传入传出参数实现返回。
这是两种方式来获取链表的头节点:一种是传二重指针进去,第二种就是传一重指针,但是返回值返回头节点地址;当然,还有第三种,就是两个都做,不过没必要。