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