链表
单链表
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。