结构体数组简单实用,但如果要在指定位置完成插入或者删除一个元素的操作室一件很麻烦的,它需要移动后面多个元素的操作,而且数组的大小也不能改变,为了解决这个问题,可以采用链表数据结构。
一、链表的概述
在列表结构中将为每一个元素申请的内存单元成为结点。
struct list { int no; int score; struct list *next; };
//* listp为链表操作的当前节点,*p为新建节点,*listhead为链接头的指针
struct *p,*listp,*listhead;
//malloc分配size字节的内存,成功时返回一个指针,指向所分配的地址;失败后返回NULL
p=(struct list *)malloc(sizeof(struct list)); //申请一个新指针
listhead=p;//此次操作是首次创建新指针
listp=p;
listp->next=NULL;
listp->no=5
listp->score=86;
实例:使用链表输入输出5名学生的学号和成绩
#include<stdio.h> #include<stdlib.h> struct list { int no; int score; struct list *next; }; int main() { int k; struct list *p,*listhead,*listp; for(k=1;k<=5;k++){ p = (struct list*)malloc(sizeof(struct list)); if(k==1){ listhead=p; } else{ listp->next=p; } listp = p; listp->next = NULL; printf("please input %d number and score:",k); scanf("%d %d",&listp->no,&listp->score); } //打印输出各个节点 p = listhead; while(p!=NULL) { printf("%d student score is %d ",p->no,p->score); p = p->next; } return 0; p = listhead; //释放各个结点的内存空间 while(p!=NULL){ listp=p; p=p->next; free(listp); } }
二、链表的基本操作
(1)建立链表
(2)输出链表中的所有结点数据信息
(3)在链表插入新的结点
(4)删除链表某个结点
#include<stdlib.h> #include<stdio.h> struct list{ int data; struct list *next; }; struct list *dele(struct list *head); struct list *insert(struct list *head); void display(struct list *head); struct list * create(); struct list * deleall(struct list *listhead); int main() { int ch; struct list * head; head = NULL; while(1){ printf("1.建立链表 "); printf("2.插入节点 "); printf("3.删除节点 "); printf("4.显示节点 "); printf("0.退出程序 "); scanf("%d",&ch); switch(ch){ case 1: head = create(); break; case 2: head = insert(head); break; case 3: head = dele(head); break; case 4: display(head); break; case 0: head = deleall(head); } if(ch == 0) break; } return 0; } struct list *create(){ struct list *listhead,*p,*listp; int x; listhead = NULL; printf("输入成绩:"); scanf("%d",&x); while(x!=-1){ if((p=(struct list *)malloc(sizeof(struct list)))==NULL){ printf("内存申请错误!"); exit(0); } if(listhead == NULL){ listhead = p; } else{ listp->next=p; } listp=p; listp->data=x; listp->next=NULL; printf("请输入下一个值(-1结束输入)"); scanf("%d",&x); } return listhead; } void display(struct list *listhead){ struct list *p; if(listhead == NULL){ printf("链表为空! "); return ; } p = listhead; while(p!=NULL){ printf("%d ",p->data); p = p->next; } } struct list *insert(struct list *listhead){ struct list *p,*listp; int k,i,x; if(listhead==NULL){ printf("链表还没有建立"); return listhead; } printf("请输入需要插入的数据和w位置"); scanf("%d %d",&x,&i); k = 1; listp=listhead; while(listp!=NULL&&k<i-1){ listp=listp->next; k=k+1; } if(k<i-1||i<1){ printf("无效插入点! "); } else if(i==1){ if((p=(struct list *)malloc(sizeof(struct list)))==NULL){ printf("申请内存错误!"); exit (0); } p->data = x; p->next=listhead; listhead = p; } else{ if((p=(struct list *)malloc(sizeof(struct list)))==NULL){ printf("申请内存错误!"); exit (0); } p->data=x; p->next=listp->next; listp->next=p; } return listhead; } struct list *dele(struct list *listhead){ struct list *listp,*p; int i,k; if(listhead == NULL){ printf("次链表为空!"); return listhead; } printf("请输入要删除的结点 "); scanf("%d",&i); k=1; listp=listhead; while(listp!=NULL&&k<i-1){ listp=listp->next; k=k+1; } if(k<i-1 || i<1){ printf("此节点为无效插入点 "); } else if(k==1){ p=listhead; listhead=p->next; free(p); } else if (i>1 && k>=i-1){ p =listp->next; listp->next=p->next; free(p); } return listhead; } struct list *deleall(struct list *listhead){ struct list *p; p = listhead; while(p!=NULL){ listhead=p->next; free(p); p=listhead; } return p; }
运行结果图