链表的增删查改

#include <stdio.h>
#include<stdlib.h>

typedef struct student {
    int num;
    float score;
    struct student* pnext;
}stu, * pstu;

void list_head_insert(pstu* pphead, stu** pptail, int i) {                   //头插法
    pstu pnew = (pstu)malloc(sizeof(stu));                                  //申请结构体节点的空间
    pnew->num = i;
    pnew->pnext = NULL;
    if (*pphead == NULL) { *pphead = pnew; *pptail = pnew; }                 //链表为空,头尾指针都指向新节点
    else { pnew->pnext = *pphead; *pphead = pnew; }                          //新节点*pnext指向原本头节点,新节点作为头节点
}

void list_tail_insert(pstu* pphead, stu** pptail, int i) {              //尾插法
    pstu pnew = (pstu)calloc(1, sizeof(stu));                         //申请结构体节点的空间,calloc不用初始化节点pnext
    pnew->num = i;
    if (*pphead == NULL) { *pphead = pnew; *pptail = pnew; }      //链表为空,头尾指针都指向新节点
    else {(*pptail)->pnext = pnew; *pptail = pnew; }             //原本尾节点的*pnext指向新节点,新节点作为尾节点
}
void list_print(pstu phead)
{
    while (phead)
    {
        printf("%d %5.1f\n", phead->num,phead->score);
        phead = phead->pnext;
    }
}

void list_sort_insert(pstu* pphead, stu** pptail, int i) {
    pstu pnew = (pstu)calloc(1, sizeof(stu));
    pnew->num = i;
    pstu pcur, ppre;
    pcur = ppre = *pphead;
    if (*pphead == NULL) { *pphead = pnew; *pptail = pnew; }                            //链表为空,头尾指针指向新节点
    else if (i < (*pphead)->num) { pnew->pnext = *pphead; *pphead = pnew; }             //判断是否插入头部,头插法
    else {                                                                              //否则插入
        while (pcur) {
            if (i > (pcur->num)) { ppre = pcur; pcur = pcur->pnext; }               //插入值大于pcur->num,ppre指向pcur,pcur指向下一个节点
            else { ppre->pnext = pnew; pnew->pnext = pcur; break; }                  //ppre节点的pnext指向新节点,新节点的pnext指向pcur
        }
        if(pcur==NULL){ (*pptail)->pnext = pnew; *pptail = pnew; }               //插入到尾部,尾插法
    }
}
void list_delete(pstu* pphead, stu** pptail, int i)                 //链表删除
{
    pstu pcur;
    pcur = *pphead;
    if (*pphead == NULL) { printf("List is empty\n"); return; }    //链表为空
    else if ((*pphead)->num == i)                               //删除的是头节点
    { 
        *pphead = pcur->pnext;
        if (*pphead == NULL) { *pptail=NULL; }      //是头节点且只有一个节点,尾指针也为null
    }
    else {                                       //删除的是中间节点 或尾节点 或没有这个数
        pstu ppre = pcur;
        while (pcur)                                    //遍历链表匹配
        {
            if (pcur->num == i)                         //删除的是中间节点
            {
                ppre->pnext = pcur->pnext;
                break;
            }
            ppre = pcur;
            pcur = pcur->pnext;
        }
        if (pcur == NULL) {                                       //没找到
            printf("Don't find this number\n");
            return; 
        }       
        if (pcur == *pptail) { *pptail = ppre; }            //删除的是尾节点
    }
    free(pcur);
    pcur = NULL;
}

void listModify(pstu phead, int num, float score)
{
    while (phead)
    {
        if (phead->num == num)
        {
            phead->score = score;
            break;
        }
        phead = phead->pnext;
    }
    if (NULL == phead)
    {
        printf("Don't find modify num\n");
    }
}
int main() {
    pstu phead, ptail;
    phead = ptail = NULL;
    int i,m;
    float score;
    while (scanf_s("%d", &i) != EOF)
    {
        list_sort_insert(&phead, &ptail, i);
    }
    list_print(phead);
   while (printf("\nthe delete number is:"), fflush(stdout), scanf_s("%d",&m) != EOF) {
        list_delete(&phead, &ptail, m);
        list_print(phead);
    }
    while (printf("\nthe modify number is:"), fflush(stdout), scanf_s("%d%f",&m,&score) != EOF) {
        listModify (phead, m,score);
        list_print(phead);
    }
    return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值