一:链表的定义
链表节点的定义:
二:静态链表
#include <stdio.h> typedef struct stu { //数据域 int num; char name[32]; float score; //指针域 //next保存下一个节点的地址 编号 struct stu *next; }STU; void test01() { STU data1={100,"lucy",89.1,NULL}; STU data2={101,"lucy1",89.1,NULL}; STU data3={102,"lucy2",89.1,NULL}; STU data4={103,"lucy3",89.1,NULL}; //链表头 STU *head = &data1; data1.next = &data2; data2.next = &data3; data3.next = &data4; //遍历 STU *pb = head; while(pb != NULL) { printf("%d %s %f\n", pb->num, pb->name,pb->score); //去往下一个节点 pb = pb->next; } } int main(int argc, char const *argv[]) { test01(); return 0; }
三:链表的插入操作
1,在链表头部插入节点
```c STU* insert_link(STU *head, STU tmp) { //1、为插入的节点 申请 堆区空间 STU *pi = (STU *)calloc(1,sizeof(STU)); //2、将tmp的数据 赋值到 *pi中 *pi = tmp; //将pi->next赋值为NULL pi->next = NULL; //3、判断链表是否为NULL if(head == NULL)//链表不存在 { head = pi; //return head; } else//链表存在 { //让pi->next指向旧的head节点 pi->next = head; //更新头节点 信息 head = pi; //return head; } return head; } ```
2,在链表尾部插入节点
```c //尾部插入 STU* insert_link(STU *head, STU tmp) { //1、为带插入的节点 申请空间 STU *pi = (STU *)calloc(1,sizeof(STU)); //2、将tmp的数据 赋值给*pi *pi = tmp; pi->next = NULL; //3、判断链表 是否存在 if(head == NULL)//不存在 { head = pi; //return head; } else//存在 { //寻找尾节点 STU *pb = head; while(pb->next != NULL) { pb = pb->next; } //将尾节点的 指针域next 指向新的pi节点 pb->next = pi; //return head; } return head; } ```
3,有序插入链表节点
//链表的有序插入 STU* insert_link(STU *head, STU tmp) { //1、为待插入的节点 申请空间 STU *pi = (STU *)calloc(1,sizeof(STU)); //2、将tmp的数据 赋值给*pi *pi = tmp; pi->next = NULL; //判断链表 是否为空 if(head == NULL)//为NULL { head = pi; return head; } else//不为空 { //逐个节点寻找插入点的位置 STU *pf = head, *pb = head; //pb->num < pi->num 按照num从小-->大排 //pb->next != NULL 防止链表 查询越界 while((pb->num < pi->num) && (pb->next != NULL)) { //pf记录pb移动之前的位置 pf = pb; pb往下一个节点移动 pb = pb->next; } //判断插入点的位置(前 中 尾) if(pb->num >= pi->num)//前 中 { if(pb == head)//头部前 插入 { pi->next = head;//保存旧链表的头地址 head = pi;//跟新新链表头地址 } else//中部 插入 { pf->next = pi; pi->next = pb; } } else if(pb->next == NULL)//尾部 { pb->next = pi; } } return head;//重要 }
四:链表的遍历
void print_link(const STU *head) { //1、判断链表 是否存在 if(head == NULL)//不存在 { printf("链表不存在\n"); return; } else//存在 { const STU *pb = head; while(pb != NULL) { printf("num=%d, name=%s, score=%f\n", pb->num, pb->name, pb->score); pb = pb->next; } } }
五:链表的查找
STU* find_link(STU *head, char *name) { //1、判断链表是否存在 if(head == NULL) { printf("链表不存在\n"); return NULL; } else//链表存在 { //逐个节点查询 STU *pb = head; while((strcmp(pb->name, name) != 0) && (pb->next != NULL)) { pb = pb->next; } //判断越界 还是找到相应的节点 if(strcmp(pb->name, name) == 0)//找到 { return pb; } else if(pb->next == NULL)//未找到 { printf("未找到姓名为%s的节点信息\n", name); return NULL; } } return NULL; }
六:删除链表指定节点
STU* delete_link(STU *head,float score) { //判断链表是否存在 if(head == NULL)//不存在 { printf("链表不存在\n"); return head; } else//存在 { //逐个节点查询删除点 STU *pf = head, *pb = head; while((pb->score != score) && (pb->next != NULL)) { pf = pb; pb = pb->next; } if(pb->score == score)//找到删除点 { if(pb ==head)//删除头节点 { head = head->next; } else//删除中、尾节点 { pf->next = pb->next; } //释放要删除的节点 free(pb); printf("节点删除成功\n"); return head; } else//未找到删除点 { printf("未找到删除点\n"); return head;//重要 } } return head; }
七:释放整个链表
STU *free_link(STU *head) { //判断链表 是否存在 if(head == NULL) { printf("链表不存在\n"); return head; } else//存在 { STU *pb = head; //逐个节点释放 while(pb != NULL) { //head记录下一个节点的位置 head = head->next; //释放pb free(pb); //更新pb的位置 pb = head; } return head; } return head; }