前言
本程序用实现了链表的头插尾插,对文件读取的应用,基本的插删工作,并对部分操作注释了自己的理解,程序并不复杂,单由于个人水平有限可能还有不足,欢迎各位大佬指正 作者学号(2019060745)
1.引入库函数
代码如下(示例):
#include <stdio.h>
#include <stdlib.h>
#include <malloc.h>
2.读入数据
link *qqqqqqqqqq() { //!从文件中导出到链表
FILE *fp;
fp = fopen("D:\\lianbiao12.txt", "r");
link *head, *next, *end;
head = (link *)malloc(sizeof(link));
head->LNond = NULL;
end = head;
while (!feof(fp)) { //feof函数有俩个返回值,非文件尾返回0,文件尾返回非0
next = (link *)malloc(sizeof(link));
fscanf(fp,"%d", &next->date); //1 表示从fp指向的文件中读取一个量存入变量
end->LNond = next;
end = next;
}
end->LNond = NULL;
fclose(fp);
return (head);
}
总结
-
#include <stdio.h> #include <stdlib.h> #include <malloc.h> typedef struct link { int date; struct link* LNond; } link; link *InsScanf_after();//!输入 尾插 link *InsScanf_first();//头插 void InsFile_txt(link *head); //!保存数据到文件 link *qqqqqqqqqq(); //!从文件中导出到链表 void InsBefore(link *head);//!插入元素 void InsPrintf(link *head); //!输出到控制台 void InsDelete(link *head);//!删除元素 void InsLength(link *head); //!表长 void Getelem_L(link *head); //!查找元素 void minu(); void minu() { { link *HeadReturn = NULL; int number; printf("您选择了“链表”\n"); printf("##############################\n"); printf("# 1----前插建立链表 #\n"); printf("# 2----后插建立链表 #\n"); printf("# 3----插入 #\n"); printf("# 4----输出到控制台 #\n"); printf("# 5----删除 #\n"); printf("# 6----求线性表的表长 #\n"); printf("# 7----访问第i个元素 #\n"); printf("# 8----从文件中导出到链表 #\n"); printf("# 9----写入文件 #\n"); printf("# 0----退出 #\n"); printf("##############################\n"); printf("请输入选择:(0-6):"); scanf("%d", &number); while (number != 0) { switch (number) { case 1: HeadReturn = InsScanf_after(); break; case 2: HeadReturn =InsScanf_first(); break; //!头插 case 3: InsBefore(HeadReturn); break; //!插入 case 8: HeadReturn=qqqqqqqqqq(); break; //!从文件中导出到链表 case 4: InsPrintf(HeadReturn); break; //!输出到控制台 case 5: InsDelete(HeadReturn); break; //!删除 case 6: InsLength(HeadReturn); break; //!表长 case 7: Getelem_L(HeadReturn); break; //!查找 case 9: InsFile_txt(HeadReturn); break; //!有待开发的文件 } printf("输入下一步操作\n"); scanf("%d", &number); } } } link *InsScanf_after() { //!输入 尾插 int i = 0; link *head, *next, *end; head = (link*)malloc(sizeof(link)); if (head) printf("已分配空间,请输入链表长度\n"); scanf("%d", &head->date); head->LNond = NULL; end = head; while (i < head->date) { next = (link*)malloc(sizeof(link)); scanf("%d", &next->date); next->LNond = NULL; end->LNond = next;//新结点放入end指针域或者说end指向新结点 end = next;//把next作为新的尾结点end i++; } next->LNond = NULL; end = next; return head; } link *InsScanf_first() { //头插:插到头结点和首元节点(第一个结点)之间 int i = 0; link *head,*s_new; head = (link*)malloc(sizeof(link)); if (head) printf("已分配空间,请输入链表长度\n"); scanf("%d", &head->date); s_new = (link*)malloc(sizeof(link));//生成首元结点 scanf("%d", &s_new->date); head->LNond =s_new; s_new->LNond=NULL; while(i < head->date-1) { s_new = (link*)malloc(sizeof(link)); scanf("%d", &s_new->date); s_new->LNond = head->LNond; //将新结点插入到头结点和首元节点之间 head->LNond = s_new;//新结点放入head指针域或者说head指向新结点 i++; } return head; } void InsFile_txt(link *head) { //!保存数据到文件 link *next; next = head->LNond; FILE *fp; fp = fopen("D:\\lianbiao12.txt", "a+"); while (next != NULL) { fprintf(fp, " %d", next->date); next = next->LNond; } getchar(); fclose(fp); printf("输出成功"); } link *qqqqqqqqqq() { //!从文件中导出到链表 //int i = 0; //int a; FILE *fp; fp = fopen("D:\\lianbiao12.txt", "r"); //int *p1; link *head, *next, *end; head = (link *)malloc(sizeof(link)); head->LNond = NULL; end = head; while (!feof(fp)) { //feof函数有俩个返回值,非文件尾返回0,文件尾返回非0 next = (link *)malloc(sizeof(link)); fscanf(fp,"%d", &next->date); //1 表示从fp指向的文件中读取一个量存入变量 end->LNond = next; end = next; } end->LNond = NULL; fclose(fp); return (head); } void InsBefore(link *head) { //!插入元素 int i = 0, a = 0, Check = 1; //循环次数 位置 位置校验 link *next, *p; next = head;//此处用head而不用head->LNond的原因为:head内存放的是第一个结点next的地址,如果用head->LNond则会丢失头结点地址( //头结点内储存的数据还在,也可正常输出),导致插入的元素位置实际为想要插入位置后一位 while (Check) { printf("请输入要插入元素位置(输0退出)"); scanf("%d", &a); if (a <= head->date + 1 && a > 0) Check = 0; else if(a==0) return; else printf("位置不合理,请重新输入\n"); } while ((next->LNond) && i < a - 1) { next = next->LNond; i++; } printf("要插入的值为:"); p = (link*)malloc(sizeof(link)); scanf("%d", &p->date); p->LNond = next->LNond; //将 工作指针next->内存放的下一结点的地址存放到插入结点P->LNond内 next->LNond = p; //用插入结点p的地址覆盖工作指针next内存放的地址 head->date++; } void InsPrintf(link *head) { //!输出到控制台 link *next; next = head->LNond; printf("输出"); while (next) { printf("%4d", next->date); next = next->LNond; } } void InsDelete(link *head) { //!删除元素 int i = 0, a = 0; //循环次数 删除位置 link *next, *p1; next = head;//此处用head而不用head->LNond的原因为:head内存放的是第一个结点next的地址,如果用head->LNond则会丢失头结点地址( //头结点内储存的数据还在,也可正常输出),导致删除的元素实际为想要删除元素后一位的元素 printf("请输入要删除元素位置"); scanf("%d", &a); if (a > head->date) { printf("位置不存在"); return; } while ((next->LNond) && i < a - 1) { printf("%4d", next->date); next = next->LNond; i++; printf("删除的%d为%d\n", i, next->date); } p1 = next->LNond; printf("删除的为%d\n", p1->date); next->LNond = p1->LNond; free(p1); head->date--; } void InsLength(link *head) { //!表长 link *next; int n = 0; next = head->LNond; printf("输出"); while (next) { next = next->LNond; n++; } printf("表长为%d", n); head->date = n; } void Getelem_L(link *head) { //!查找元素 int i = 0, a = 0, Check = 3; //循环次数 位置 位置校验 link *next; next = head->LNond; while (Check) { printf("请输入要查找元素位置(输0退出)"); scanf("%d", &a); if ((int)a > head->date + 1) printf("位置不合理,请重新输入或退出(0)\n"); else if( a == 0) return; else Check=0; } while ((next->LNond) && i < a - 1) { next = next->LNond; i++; } printf("第%d个元素为%4d", a, next->date); } int main() { minu(); return 0; }