单向链表节点的删除

本文深入探讨了单向链表中节点的删除操作,包括删除头节点、中间节点和尾节点。通过具体例子,阐述了查找目标节点并进行删除的步骤。文章涵盖了不同场景,如删除关键字为key的节点、最大值节点的处理,以及如何处理数据域值重复的情况。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

单向链表的创建在这里不在赘述,详细请看另一篇文章《单向链表的创建》。在本篇文章中,主要通过举例的方式来帮大家理解单向链表节点的删除。

本篇文章中创建节点用如下表示

typdef struct node{  
    int date;//定义数据域  
    struct node * next;//定义指针域  
} ElemSN;  

在链表节点的删除中,可以分为两种情况

①删除头节点

pDel=head;//定义指针指向待删节点
head=head->next;//挪动头指针
free(pDel);//释放待删除指针完成删除
pDel=NULL;//原指针指空

②删除中间节点、尾节点

q->next=pDel->next;//q为待删除节点的前驱节点指针,pDel为待删除节点指针
free(pDel);
pDel=NULL;

删除目标节点可概括为两步:

查找目标节点、删除

例一:设head指向一个非空单向链表、其数据域的值不重复,在链表中删除关键字为key的节点

ElemSN  *DelKeyNode(ElemSN *head,int key)
{
    ElemSN *p,*q;
    for(p=head,q=NULL;p&&p->data!=key;q=p;p=p->next);//两指针连动,p指向待删除节点,q指向其前驱节点
    if(!p)
        printf("NOT FOUND");
    else{ 
        if(p==head)
            head=head->next;
        else
            q->next=p->next;
        free(p);
        p=NULL;
    }
    return head;
}

例二:设数据域值不重复

            ①删除链表中最大值节点

ElemSN *DelMaxNode(ElemSN *head)
{
    ElemSN *qmax,*pmax,*p;
    for(pmax=p=head;p;p=p->next)
        if(pmax->data<p->data)
            pmax=p;
    if(pmax!=head){
        for(qmax=head;qmax->next!=pmax;qmax=qmax->next);
        qmax->next=pmax->next;
    }
    else
        head=head->next;
    pmax->next=NULL;
    free(pmax);
    return head;
}

        ②将链表中最大值节点移动到尾部

ElemSN *MovMaxNodeToTail(ElemSN *head)
{
    ElemSN *qmax,*pmax,*p;
    for(pmax=p=head;p;p=p->next)
        if(pmax->data<p->data)
            pmax=p;
    for(p=head;p->next;p=p->next);
    if(pmax!=head){
        for(qmax=head;qmax->next!=pmax;qmax=qmax->next);
        qmax->next=pmax->next;
    }
    else
        head=head->next;
    pmax->next=NULL;
    p->next=pmax;
    return head;
}

例三:设数据域值重复,删除关键值为key的节点

ElemSN *DelKeyNode(ElemSN *head,int key)
{
    ElemSN *q,*p;
    p=head;
    while(p){
        if(p->data!=key){
            q=p;
            p=p->next;
        }
        else{
            if(p==head){
                head=head->next;
                free(p);
                p=head
            }
            else{
                q->next=p->next;
                free(p);
                p=q->next;
            }                
    }
    return head;
}

例四::设head指向一个非空单向链,数据域值重复,且升序有序,删除链表中重复值的节点

void DelNodes(ElemSN *head)
{
    ElemSN *q,*p;
    q=head;
    p=head->next;
    while(p){
        if(p->data==q->data){
            q->next=p->next
            free(p);
            p=q->next;
        }
        else{
            q=p;
            p=p->next;
        }
    }
}

例五:设head指向一个非空单向链表,数据域的值重复且无序,删除重复值节点

void DelSameNodes(ElemSN *head)
{
    ElemSN *p,*q,*pkey;
    pkey=head;
    while(pkey){
        q=pkey;
        p=q->next;
        while(p){
            if(pkey==p){
                q->next=p->next;
                free(p);
                p=q->next;
            }
            else{
                q=p;
                p=p->next;
            } 
        }
        pkey=pkey->next;
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值