当前位置: 首页 > news >正文

链表与文件

链表

单链表

1.链表的初始化

typedef struct node
{char name[100];int  number;struct node *next;
}Node,*LinkList;}Node;

2.链表的初始化函数(Initlist)

LinkList InitList()
{LinkList head;head=(Node*)malloc(sizeof(Node));head->next=NULL;return head;
}

3.建立链表(Creatbyrear/Creatbyhead)

(1)尾插法

有头节点

void CreatByRear(LinkList head)
{Node *r,s;char name[100];int  number;r=head;printf("输入");while(1){scanf("%s",name);scanf("%d",&number);if(number==0){break;}
*                s=(Node*)malloc(sizeof(Node));strcpy(s->name,name);s->number=number;r->next=s;r=s;}r->next=NULL;
}

无头结点

Node* Creatbyrear()
{Node* head;head=NULL;Node *p,r;while(1){char name[100];int number;scanf("%s",name);scanf("%d",&number);if(number==0){break;}
*                p=(Node*)malloc(sizeof(Node));strcpy(p->name,name);p->number=number;p->next=NULL;if(NULL==head){head=p;r=head;}else{r->next=p;r=p;}}return head;
}
(2)头插法

有头节点

void CreatByHead(LinkList head)
{Node s;char name[100];int number;printf("输入");while(1){scanf("%s",name);scanf("%d",&number);if(number==0){break;}
*                s=(Node*)malloc(sizeof(Node));strcpy(s->name,name);s->number=number;s->next=head->next;head->next=s;}
}

无头结点

Node* Creatbyhead()
{Node *head;head=NULL;Node s;printf("输入\n");while(1){int number;char name[100];scanf("%s",name);scanf("%d",&number);if(number==0){break;}*s=(Node*)malloc(sizeof(Node));strcpy(s->name,name);s->number=number;s->next=head;head=s;}return head;
}

4.输出(Output)

有头节点

void OutPut(LinkList head)
{Node *p;p=head->next;printf("输出\n");while(p){printf("%s ",p->name);printf("%d\n",p->number);p=p->next;}
}

无头结点

void Output(Node *head)
{Node *p;p=head;while(p){printf("%s ",p->name);printf("%d\n",p->number);p=p->next;}
}

5.插入(Insert)

有头节点

void Insert(LinkList head,int i)
{Node *p=head,s;int j=0;while(j<i-1&&p){p=p->next;j++;}if(p){printf("插入");*s=(Node*)malloc(sizeof(Node));scanf("%s",s->name);scanf("%d",&s->number);s->next=p->next;p->next=s;}
}

头插入

void InsertHead(LinkList head)
{Node s;*s=(Node*)malloc(sizeof(Node));printf("头插入");scanf("%s",s->name);scanf("%d",&s->number);s->next=head->next;head->next=s;} 

尾插入

void InsertRear(LinkList head)
{Node *p=head,s;while(p&&p->next){p=p->next;}if(p){printf("末插入");
*                s=(Node*)malloc(sizeof(Node));scanf("%s",s->name);scanf("%d",&s->number);p->next=s;s->next=NULL;}}

无头结点

Node* Insertlist(Node *head,int pos)
{printf("插入\n");Node *s,p;*s=(Node*)malloc(sizeof(Node));scanf("%s",s->name);scanf("%d",&s->number);if(pos==1){s->next=head;head=s;}else{p=head;int j=1;while(j<pos-1&&p){p=p->next;j++;}if(p){s->next=p->next;p->next=s;}}return head;
}

6.删除(Delete)

有头节点

void Delete(LinkList head,int pos)
{Node *r=head,*p;int j=0;printf("删除后");while(j<pos-1&&r){r=r->next;j++;}if(r==NULL||r->next==NULL){printf("Error!");}else{p=r->next;r->next=p->next;free(p);}}

无头结点

Node* Delete(Node *head,int pos)
{printf("删除后的");Node *p,*q;p=head;if(head==NULL){printf("ERROR!");}else if(pos==1){q=head;head=head->next;free(q);}else{int j=1;while(j<pos-1&&p){p=p->next;j++;}if(p==NULL||p->next==NULL){printf("ERROR");}else{q=p->next;p->next=q->next;free(q);}}return head;
}

7.查询(Search)

有头节点

Node* Search(LinkList head,char name[])
{Node *p=head->next;while(p){if(strcmp(p->name,name)!=0){p=p->next;}else{break;}if(p=NULL){printf("error!") ;}return p;}
}

无头结点

void Search(Node *head)
{printf("查询");Node *p;p=head;int t=0;char name[100];scanf("%s",name);while(1){if(strcmp(p->name,name)==0){printf("%s ",p->name);printf("%d\n",p->number);t++;}p=p->next;if(p==NULL){break;}}if(t==0){printf("ERROR!");}
}

8.长度(Length)

有头节点

int ListLength(LinkList head)
{int sum=0;Node *p=head->next;while(p){p=p->next;sum++;}return sum;} 

无头结点

void Length(Node *head)
{printf("长度\n");Node *p;int count=0;p=head;while(p){if(p==NULL){break;}else{p=p->next;count++;}}printf("%d",count);
}

9.合并链表(Merge)

有头节点

void Merge(LinkList a,LinkList b){Node *p,*q,*r;LinkList c;p=a->next;q=b->next;r=c=a;while(p&&q){if(p->number<q->number){r->next=p;r=p;p=p->next;}else{r->next=q;r=q;q=q->next;}}while(p){r->next=p;r=p;p=p->next;}while(q){r->next=q;r=q;q=q->next;}free(b);}

10.逆置(Reverse)

有头节点

void Reverse(LinkList head)
{Node *p,*q;p=head->next;head->next=NULL;while(p){q=p->next;p->next=head->next;head->next=p;p=q;}}
Node* Reverse (Node *head)
{    //三指针法if (head == NULL || head->next == NULL){return head;}Node *p = NULL;Node *q = head->next;Node *next ;while (q != NULL) {next = q->next;q->next = p;p = q;q = next;}head->next=p;return head;
}

无头结点

Node* Reverse(Node* head){Node *p,*q;p=head->next;if(head==NULL){return 0;}if(head->next==NULL)    {return head;}    head->next=NULL;while(p->next!=NULL){q=p->next;p->next=head;head=p;p=q;}p->next=head;head=p;return head;}

11.main函数

有头节点

int main()
{LinkList a,b;a=InitList();CreatByRear(a);OutPut(a);Insert(a,2);OutPut(a);InsertHead(a);OutPut(a);InsertRear(a);OutPut(a);Delete(a,4);OutPut(a);int sum;sum=ListLength(a);printf("%d\n",sum);b=InitList();CreatByHead(b);OutPut(b);Delete(b,4);OutPut(b);Merge(a,b);OutPut(a);Reverse(a);OutPut(a);return 0;
}

无头结点

int main()
{node *a,*b;a=CreatByRear(a);OutPut(a);a=Insert(a,2);OutPut(a);Delete(a,4);OutPut(a);ListLength(a);b=CreatByHead(b);OutPut(b);Delete(b,4);OutPut(b);Merge(a,b);OutPut(a);a=Reverse(a);OutPut(a);return 0;
}

循环链表

  • 循环链表是一种特殊的链表数据结构,与单向链表或双向链表相比,循环链表的最后一个节点的下一个节点指向第一个节点,从而形成一个环形结构。因此,循环链表可以在最后一个节点后继续添加节点,并且可以像单向链表或双向链表一样遍历、查找和删除节点。循环链表通常有一个头指针和一个尾指针,它们指向第一个节点和最后一个节点,以便在添加或删除节点时快速定位。

  • p->next==head,判断该节点的指针域是否指向链表头节点。

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
typedef struct node
{char name[100];int number;struct node *next;
}Node;
Node* Initlist()//初始化
{Node *head;head=(Node*)malloc(sizeof(Node));head->next=NULL;return head;
}
void Creatbyrear(Node *head)//尾插法
{printf("输入\n");Node *r,*s;char name[100];int number;r=head;while(1){s=(Node*)malloc(sizeof(Node));scanf("%s",name);scanf("%d",&number);if(number==0){break;}strcpy(s->name,name);s->number=number;r->next=s;r=s;}r->next=head;
}
void Output(Node* head)//输出
{printf("输出\n");Node *s;s=head->next;while(!(s==head)){printf("%s %d\n",s->name,s->number);s=s->next;}
}
void Creatbyhead(Node* head)//头插法
{Node *s;char name[100];int number;printf("输入");while(1){scanf("%s",name);scanf("%d",&number);if(number==0){break;}s=(Node*)malloc(sizeof(Node));strcpy(s->name,name);s->number=number;s->next=head->next;head->next=s;}
}
void Delete(Node* head,int pos)//删除{Node *r=head,*p;int j=0;printf("删除后\n");do{r=r->next;j++;}while(j<pos-1&&(r!=head));if(r==head||r->next==head){printf("Error!");}else{p=r->next;r->next=r->next->next;free(p);Output(head);}}void Insert(Node* head,int i)//插入
{Node *p=head,*s;int j=0;while(j<i-1&&p){p=p->next;j++;}if(p){printf("插入\n");s=(Node*)malloc(sizeof(Node));scanf("%s",s->name);scanf("%d",&s->number);s->next=p->next;p->next=s;}
}
void Inserthead(Node* head)//头插入
{Node *s;s=(Node*)malloc(sizeof(Node));printf("头插入\n"); scanf("%s",s->name);scanf("%d",&s->number);s->next=head->next;head->next=s; } void Insertrear(Node* head)//尾插入{Node *p=head,*s;while((p->next!=head)){p=p->next;}if(p){printf("末插入");s=(Node*)malloc(sizeof(Node));scanf("%s",s->name);scanf("%d",&s->number);p->next=s;s->next=head; }}Node* Search(Node* head,char name[])//查询
{printf("查询\n");Node *p=head->next;while(p!=head){if(strcmp(p->name,name)!=0){p=p->next;}else{break;}}if(p==head){printf("error!") ;}return p;
}
void Listlength(Node* head)//长度
{printf("链表长度:\n");int sum=0;Node *p=head->next;while(p!=head){p=p->next;sum++;}printf("%d",sum); } Node* Reverse (Node *head)//逆置{    //三指针法if (head == NULL || head->next == NULL){return head;}Node *p = NULL;Node *q = head->next;Node *next ;while (q != head) {next = q->next;q->next = p;p = q;q = next;}head->next=p;return head;
}
int main()
{Node *a,*b;a=Initlist();Creatbyrear(a);Delete(a,2);a=Reverse(a);Output(a); return 0;
}

文件

打开文件

 FILE *fp;fp=fopen("d:/masm.rar/string.h","wt");

r :read 读,以只读的方式打开文件,文件必须存在!
w :write 写,以只写的方式打开文件,文件如果存在则打开并 清空文件内容,反之新建一个同名文件
a :append 追加,以追加的方式打开文件,文件如果存在则打开,不清除原内容,并在原内容之后,文件尾标志EOF之前继续写入,反之新建一个同名文件
t :text 文本文件,可忽略不写
b :binary 二进制文件
+:w+r 允许读和写

关闭文件

fclose(fp);

成功,返回0;发生错误,返回非0值;

获取文件的属性

fileno()
功 能:把文件流指针转换成文件描述符
表头文件:#include <stdlib.h>
定义函数:int fileno(FILE *fp)
返回值 :返回和fp文件流对应的文件描述符。如果失败,返回-1。

filelength()
功 能:返回文件描述字对应的文件大小,以字节为单位。
表头文件:#include<io.h>
定义函数:long filelength(int handle_no);

#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<ctype.h>
#include<io.h>
int main()
{FILE *fp;int fno,fsize;char ch;gets(filename);fp=fopen(filename,"a+");fno=fileno(fp);fsize=filelength(fno);printf("%d\n",fsize);fclose(fp);return 0;} 

文件的顺序读写

单字符读写函数

fgetc()
fputc()

#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<ctype.h>
#include<io.h>
int main()
{FILE *fp;int i;char filename[1000];char ch;gets(filename);fp=fopen(filename,"a+");while((ch=fgetc(fp))!=EOF){printf("%c",ch);}char data[10000];while(1){if(toupper(getche())=='Y'){gets(data);for(i=0;i<strlen(data);i++){fputc(data[i],fp);}}else{fclose;getche();break;}}fp=fopen(filename,"rt");if(fp==NULL){getch();exit(1);}while((ch=fgetc(fp))!=EOF);{printf("%c",ch);}fclose(fp);return 0;} 

字符串的读写函数

fgets()
fputs()

#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<io.h>
#include<ctype.h>
int main()
{FILE *fp;char filename[1000],data[1000];gets(filename);fp=fopen(filename,"at+");if(fp==NULL){getche();exit(1);}while((fgets(data,10,fp))!=NULL){printf("%s",data);}while(1){if(toupper(getche())=='Y'){gets(data);fputs(data,fp);}else{fclose(fp);exit(1);}}fopen(filename,"rt");if(fp==NULL){exit(1);}while(fgets(data,10,fp)!=NULL){printf("%s",data);}fclose(fp);return 0;
}
#include<stdio.h>
#include<string.h>
#include<io.h>
#include<stdlib.h>
int main()
{FILE *fp;int i,j,count,count1;char string[1000000],t,ch;fp=fopen("d:/masm.rar/lab0555.asm","rt");if(fp==NULL){exit(1);}for(i=0;(ch=fgetc(fp))!=EOF;i++){string[i]=ch;putchar(string[i]);}fclose(fp);count1=i;fp=fopen("d:/masm.rar/DOSBox 0.74","rt");if(fp==NULL){exit(1);}for(i=count1;(ch=fgetc(fp))!=EOF;i++){string[i]=ch;printf("%c",string[i]);}fclose(fp);count=i;for(i=0;i<count;i++){for(j=i+1;j<count;j++){if(string[i]<string[j]){t=string[i];string[i]=string[j];string[j];}}}fp=fopen("d:/masm.rar/string.h","wt");fputs(string,fp);fclose(fp);return 0;} 

格式化字符串读写函数

fscanf()
fprintf()

#include<stdio.h>
#include<stdlib.h>
int main()
{struct student{char num[100];char name[100];char sex[100];}class[100];FILE *fp;int i;fp=fopen("d:/masm.rar/list","wt");if(fp==NULL){exit(1);}else{for(i=0;i<3;i++){scanf("%s",class[i].num);scanf("%s",class[i].name);scanf("%s",class[i].sex);fprintf(fp,"%s %s %s\n",class[i].num,class[i].name,class[i].sex);}}fclose(fp);fopen("d:/masm.rar/list","rt");i=0;while(fscanf(fp,"%s %s %s",class[i].num,class[i].name,class[i].sex)!=EOF){printf("%s %s %s\n",class[i].num,class[i].name,class[i].sex);i++;}fclose(fp);return 0;
}

数据块读写操作

fread()
fwrite()

#include<stdio.h>
#include<stdlib.h>
int main()
{struct student{char num[100];char name[100];char sex[100];}class[100];FILE *fp;int i;fp=fopen("d:/masm.rar/list","wt");if(fp==NULL){exit(1);}else{for(i=0;i<3;i++){scanf("%s",class[i].num);scanf("%s",class[i].name);scanf("%s",class[i].sex);fwrite(&class[i],sizeof(struct student),1,fp);}}fclose(fp);fp=fopen("d:/masm.rar/list","rt");i=0;while(fread(&class[i],sizeof(struct student),1,fp)!=NULL){printf("%s %s %s\n",class[i].num,class[i].name,class[i].sex);i++;}fclose(fp);return 0;
}

文件的随机读写

rewind()
将文件内部的位置指针移到文件的开始位置。

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
int main()
{FILE *fp;char ch,str[20];fp=fopen("d:/masm.rar/haha","at+");if(fp==NULL){exit(1);}gets(str);fwrite(str,strlen(str),1,fp);ch=fgetc(fp);rewind(fp);while(ch!=EOF){putchar(ch);ch=fgetc(fp);}printf("\n");fclose(fp);return 0;
}

fseek()

#include<stdio.h>
#include<stdlib.h>
struct student
{        char num[20];char name[20];char sex[20];
}q;
int main()
{FILE *fp;int i=1;fp=fopen("d:/masm.rar/list","rt");if(fp==NULL){exit(1);}fseek(fp,i*sizeof(struct student),0);fread(&q,sizeof(struct student),1,fp);fclose(fp);return 0;
}

ftell()
得到位置指针的当前位置,如果返回值为-1L,则表示出错。

#include<stdio.h>
#include<stdlib.h>
struct student
{        char num[20];char name[20];char sex[20];
}q;
int main()
{FILE *fp;int i=1;fp=fopen("d:/masm.rar/list","rt");if(fp==NULL){exit(1);}int t=ftell(fp);printf("%d\n",t);fseek(fp,i*sizeof(struct student),0);fread(&q,sizeof(struct student),1,fp);t=ftell(fp);printf("%d",t);return 0;
}

putw 函数(适用于二进制文件)

putw函数表示整数输出。
其一般形式为: putw(i,fp);
功能:将整数i输出到文件fp之中。

getw 函数(只适用于二进制文件)

getw函数表示整数输入。
一般形式为:
int a;
a=getw(fp);
功能:从fp指向的文件中读取一个整数(2字节),整数由函数返回。只使用于二进制文件。

出错检查

feof(fp)

fp:文件指针变量
功能:判断文件是否处于文件结束位置。如果文件结束,则返回1,否则返回0。

ferror 函数

函数返回值:无错误出现时返回0;有错误出现时,返回一个非零值。

clearerr函数

clearerr的作用是使文件出错标志和文件结束标志置为0。假设在调用一个输入输出函数时出现错误,ferror函数值为一个非零值。应该立即调用clearerr(fp),使ferror(fp)的值变成0,以便再进行下一次的检测。只要出现文件读写出错标志,它就一直保留,直到对同一文件调用clearerr函数或rewind函数,或任何其他一个输入输出函数。
对同一个文件每一次调用输入输出函数,都会产生一个新的ferror函数值,因此,应当在调用一个输入输出函数后立即检查ferror函数的值,否则信息会丢失。在执行fopen函数时,ferror函数的初始值自动置为0。

相关文章:

  • 日志的实现
  • 强化学习笔记(三)——表格型方法(蒙特卡洛、时序差分)
  • docker学习笔记2-最佳实践
  • # 05_Elastic Stack 从入门到实践(五)
  • 【图像变换】pytorch-CycleGAN-and-pix2pix的学习笔记
  • Linux系统编程 day7、8 信号(周日划水了)
  • LangChain + 文档处理:构建智能文档问答系统 RAG 的实战指南
  • Hyperlane:Rust Web框架的性能新标杆
  • 超详细mac上用nvm安装node环境,配置npm
  • 智慧能源安全新纪元:当能源监测遇上视频联网的无限可能
  • kafka监控kafka manager(CMAK)部署配置
  • Moritex大靶面远心镜头 助力晶圆外观检测
  • 榕壹云预约咨询系统:基于ThinkPHP+MySQL+UniApp打造的灵活预约小程序解决方案
  • 【日志体系】ELK Stack与云原生日志服务
  • 【计算机视觉】CV实战项目- CMU目标检测与跟踪系统 Object Detection Tracking for Surveillance Video
  • 24. git revert
  • Spring(第一章)
  • 11-DevOps-Jenkins Pipeline流水线作业
  • 剑指offer经典题目(五)
  • ORION:通过视觉-语言指令动作生成的一个整体端到端自动驾驶框架
  • 纪念沈渭滨︱“要把近代史搞得会通”——读《士与大变动时代》随札
  • “HPV男女共防计划”北半马主题活动新闻发布会在京举办
  • 人民网评:“中国传递爱而不是关税”
  • 对话|棋后居文君:创造历史之后,还有继续追梦的心
  • 林诗栋4比1战胜梁靖崑,晋级世界杯男单决赛将和雨果争冠
  • 徐州沛县一村委会因无资质处理固废,被环保部门罚款19万元