#include <stdio.h> #include <stdlib.h> #include <stdbool.h> #include <string.h> //定义表示学生信息结点的结构体 typedef struct _student { char name[20]; float score; //定义指向链表中下一个结点的指针 struct _student* next; }student; void printlist(student*); int main( ) { //第一步:定义指向链表头和尾的指针 student* head = NULL ; student* tail = NULL ; char name[20] = "" ; float score = 0.0f ; int i = 3; bool ishead = true; printf("input student name score "); while(i--) { printf("this %d student ",i); scanf("%s %f",name,&score); //第二步“:根据结点数据创立结点 //首先,用malloc()函数动态申请内存,内存的大小就是一个结点的大小 student* node = malloc(sizeof(student)); //然后将用户输入的数据保存到这个结点 strcpy(node->name,name); node->score = score; //第三步:调整节点之间的指向关系 //如果这是链表中的第一个结点。 if(ishead) { //将指向链表首结点的head指向这个结点 head = node ; //首结点尚无下一个结点 head->next = NULL ; //当前结点就是链表的尾结点 tail = node; //首结点已经处理完毕,下一个结点就是普通结点了 ishead = false; } else { //将新结点添加到已有链表的末尾 tail->next = node; //将新的结点作为新的尾结点 tail = node; } }//第四步:重复第二步和第三步,逐个添加结点 //这里利用一个while循环重复第二步和第三步。 //直到用户用"Ctrl+z"结束数据输入为止 //将尾结点的next设置为NULL,表示这是链表的结束 if(NULL!=tail) tail->next = NULL; else return -1; //对链表进行处理… printlist(head); return 0; } void printlist(student* head) { //将首结点作为当前结点 student* node = head; //判断当前结点是否为NULL,如果不是NULL,则输出其指向的结构体数据 while(NULL!=node) { //利用当前结点结构体数据的指针访问其数据成员 printf("name: %s,score: %.2f ",node->name,node->score); //将结点所指向的下一个结点作为当前结点 node = node->next; } }
#include <stdio.h> #include <stdlib.h> struct grade { int score; struct grade *next; }; typedef struct grade NODE; //typedef为C语言的关键字,作用是为一种数据类型定义一个新名字。 //使用typedef目的一般有两个,一个是给变量一个易记且意义明确的新名字, //另一个是简化一些比较复杂的类型声明。 struct grade *create(); //创建链表 void insert(NODE *head,NODE *pnew,int i); //插入链表 void pdelete(NODE *head,int i); //删除列表 void display(NODE *head); //输出链表 void Pfree(NODE *head); //销毁链表 int main(int argc, char *argv[]) { struct grade *head,*pnew; head=create(); if (head==NULL) return 0; printf("输出创建的链表:"); display(head); pnew=(NODE *)malloc(sizeof(NODE)); if (pnew==NULL) { printf("创建失败!"); return 0; } pnew->score=88; insert(head,pnew, 3); //将新节点插入节点3的后面 printf("插入后的链表:"); display(head); pdelete(head,3); //删除节点3 printf("删除后的链表:"); display(head); Pfree(head); return 0; } struct grade *create() { NODE *head,*tail,*pnew; int score; head=(NODE *)malloc(sizeof(NODE)); //创建头节点。 if (head==NULL) { //创建失败返回 printf("创建失败!"); return NULL; } head->next=NULL; //头节点指针域置NULL tail=head; // 开始时尾指针指向头节点 printf("输入学生成绩:"); while (1) { //创建链表 scanf("%d",&score); if (score<0) //成绩为负是退出循环 break; pnew=(NODE *)malloc(sizeof(NODE)); //创建新节点 if (pnew==NULL) { //创建失败返回 printf("创建失败!"); return NULL; } pnew->score=score; //新节点数据域存放输入的成绩 pnew->next=NULL; //新节点指针域置NULL tail->next=pnew; //新节点插入到表尾 tail=pnew; //为指针指向当前的尾节点 } return head; //返回创建链表的头指针 } void insert(NODE *head,NODE *pnew,int i) { NODE *p; //当前指针 int j; p=head; for (j=0; j<i&&p!=NULL; j++) //p指向要插入的第i个节点 p=p->next; if (p==NULL) { //节点i不存在 printf("与插入的节点不存在!"); return; } pnew->next=p->next; //插入节点的指针域指向第i个节点的后继节点 p->next=pnew; //犟第i个节点的指针域指向插入的新节点 } void pdelete(NODE *head,int i) { NODE *p,*q; int j; if (i==0) //删除的是头指针,返回 return; p=head; for (j=1; j<i&&p->next!=NULL; j++) p=p->next; //将p指向要删除的第i个节点的前驱节点 if (p->next==NULL) { //表明链表中的节点不存在 printf("不存在!"); return; } q=p->next; //q指向待删除的节点 p->next=q->next; //删除节点i,也可写成p->next=p->next->next free(q); //释放节点i的内存单元 } void display(NODE *head) { NODE *p; for (p=head->next; p!=NULL; p=p->next) printf("%d ",p->score); printf(" "); } void pfree(NODE *head) { NODE *p,*q; p=head; while (p->next!=NULL) { //每次删除头节点的后继节点 q=p->next; p->next=q->next; free(q); } free(head); //最后删除头节点 } void Pfree(NODE *head) { NODE *p,*q; p=head; while (p->next!=NULL) { q=p->next; p->next=q->next; free(q); } free(p); }