C语言链表的增删查改

  小经验:在VS2017中,使用while(scanf(“%d”,&i)!= NULL){......}时,结束输入需要输入三次ctrl+z+空格

  

func.h

#include <stdlib.h>
#include <string.h>

typedef struct student {
    int number;
    struct student* pnext;
}stu, *pstu; 

void list_print(pstu);//打印
void list_head_insert(pstu*,pstu*,int);//头插法
void list_tail_insert(pstu*, pstu*, int);//尾插法
void list_sort_insert(pstu*, pstu*, int);//有序插入
void list_delete(pstu*, pstu*, int);//节点删除

func.c

#include "func.h"

void list_head_insert(pstu* pphead, pstu* pptail, int i) 
{//头插法
    pstu pnew;
    pnew = (pstu)malloc(sizeof(stu));//申请空间
    memset(pnew,0,sizeof(stu));//初始化

    pnew->number = i;

    if (*pphead == NULL) {//链表为空,新节点既是头指针,又是尾指针
        *pphead = pnew;
        *pptail = pnew;
    }
    else {
        pnew->pnext = *pphead;//原有的链表头作为新节点的pnext
        *pphead = pnew;//新节点作为节点头
    }
}

void list_tail_insert(pstu* pphead, pstu* pptail, int i)
{//尾插法实现
    pstu pnew;
    pnew = (pstu)calloc(1, sizeof(stu));//calloc会进行空间初始化
    pnew->number = i;
    if (*pptail == NULL) {
        *pphead = pnew;
        *pptail = pnew;
    }
    else
    {
        (*pptail)->pnext = pnew;//新节点变成原有尾节点的pnext
        *pptail = pnew;//新节点变成尾节点
    }
}

void list_sort_insert(pstu* pphead, pstu* pptail, int i)
{//有序插入实现
    pstu pcur,ppre;//游标
    pcur = *pphead;
    ppre = *pphead;

    pstu pnew;
    pnew = (pstu)calloc(1, sizeof(stu));//calloc会进行空间初始化
    pnew->number = i;

    if (*pptail == NULL) {//链表为空
        *pphead = pnew;
        *pptail = pnew;
    }
    else if (i<(*pphead)->number)//小于头结点,类似头插法
    {
        pnew->pnext = *pphead;//原有的链表头作为新节点的pnext
        *pphead = pnew;//新节点作为节点头
    }else
    {
        while (pcur!=NULL)
        {//插入中间
            if (i<pcur->number) 
            {
                ppre->pnext = pnew;
                pnew->pnext = pcur;
                break;
            }
            ppre = pcur;
            pcur = pcur->pnext;
        }
        if (pcur == NULL) 
        {//pcur为null,说明插入尾节点
            (*pptail)->pnext = pnew;
            *pptail = pnew;
        }
    }
}

void list_delete(pstu* pphead, pstu* pptail, int d) 
{//删除实现
    pstu ppre = *pphead, pcur = *pphead;
    if (*pphead == NULL) //链表为空
    {
        printf("List is empty\n");
        return;
    }else if(pcur->number==d)//头结点删除
    {
        *pphead = pcur->pnext;
        if (*pphead == NULL) {//删除节点后,链表为空
            *pptail = NULL;
        }
        free(pcur);
    }else//删除中间和尾部
    {
        while (pcur != NULL) 
        {
            if (pcur->number == d) 
            {
                ppre->pnext = pcur->pnext;
                break;
            }
            ppre = pcur;
            pcur = pcur->pnext;
        }
        if (pcur==*pptail) //删除的是尾节点
        {
            *pptail = ppre;
        }
        if (pcur == NULL) //未找到节点
        {
            printf("This node is not in list\n");
        }
        else
        {
            free(pcur);
        }
    }
}

void list_print(pstu phead) {
    while (phead != NULL)
    {
        printf("%3d", phead->number);
        phead = phead->pnext;
    }    
    printf("\n");
}

main.c

#include "func.h"

int main() {
    pstu phead = NULL;
    pstu ptail = NULL;
    int i;
     while(scanf("%d",&i)!=EOF)
    {
        //list_head_insert(&phead, &ptail,i);//头插法
        //list_tail_insert(&phead, &ptail, i);//尾插法
        list_sort_insert(&phead, &ptail, i);//有序插入
    }
    list_print(phead);
    while (scanf("%d", &i) != EOF) {
        list_delete(&phead, &ptail, i);
        list_print(phead);
    }
    system("pause");    
}

 

上一篇:如何在linux中的openmpi中启用多线程标志?


下一篇:华为云隐私通话(AXB)