鏈表
單鏈表
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。