C语言实现单链表删除

C语言实现单链表删除所有与条件相符的结点

删除链表的结点指若某结点数据域的值满足给定的条件,则将该节点删除。

删除链表结点有两个原则:
(1)删除操作不应该破坏原链接关系。
(2)删除结点前,应该有一个删除位置的查找子过程。

在删除一个结点时可能遇到以下三种情况:
(1)链表为空。此时不用做任何操作,直接返回。
(2)链表头就是要删除的结点。这时先用一个指针q暂存此结点,再将链表头指向下一结点,最后将q结点释放。

q = head;
head = q->next;
free(q);

(3)要删除的结点不在链表头。这时,要查找该链表中是否有要删除的结点,如果没有则返回,如果有则删除。
如果找到要删除的结点,为了不破坏原链表的链接关系,要将该结点的上一个结点链接到该结点的下一个结点上,这时需要一个记录遍历过程中结点q的上一个结点的指针p
q从第二个结点开始扫描单链表,p指向q前一节点,若q所指节点值为x,则删除,并让q后移一个节点,否则pq同步后移一个节点。

node * p, * q;
p = head;
q = p->next;
while(q != NULL)
{
    if(q->num == x)
    {
        p->next = q->next;
        free(q);
        q = p->next;
    }
    else
    {
        p = p->next;
        q = q->next;
  }
}

以前面建立的动态链表为例,编写一个删除链表中指定结点的函数Delete

node * Delete(node * head, int x)
{
    if(head == NULL)
    {
        printf("链表为空");
        return NULL;
    }
    node * p, * q;
    p = head;
    q = p->next;
    while(q != NULL)
    {
        if(q->num == x)
        {
            p->next = q->next;
            free(q);
            q = p->next;
        }
        else
        {
            p = p->next;
            q = q->next;
        }
    }
    if(head != NULL && head->num == x)
    {
        q = head;
        head = q->next;
        free(q);
        return head;
    }

    return head;
}

完整程序运行:

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

typedef struct _node
{
    int num;
    struct _node * next;
}node;

node * createlist(void);
void display(node * head);
node * Delete(node * head, int x);

int main(void)
{
    node *head;
    head = createlist();
    display(head);
    head = Delete(head, 0);
    display(head);
    return 0;
}

node * createlist(void)
{
    node * head = NULL, *p, *tail = NULL;
    int n;
    while(scanf("%d", &n) == 1)//当输入不为整数时结束
    {
        p = (node *)malloc(sizeof(node));
        
        if(head == NULL)
           head = p;
        else
           tail->next = p;
           
        p->num = n;
        p->next = NULL;
        tail = p;
    }
    return head;
}

void display(node * head)
{
    node * p;
    p = head;
    while(p != NULL)
    {
        printf("%d ",p->num);
        p = p->next;
    }
    printf("\n");
}

node * Delete(node * head, int x)
{
    if(head == NULL)
    {
        printf("链表为空");
        return NULL;
    }
    node * p, * q;
    p = head;
    q = p->next;
    while(q != NULL)
    {
        if(q->num == x)
        {
            p->next = q->next;
            free(q);
            q = p->next;
        }
        else
        {
            p = p->next;
            q = q->next;
        }
    }
    if(head != NULL && head->num == x)
    {
        q = head;
        head = q->next;
        free(q);
        return head;
    }

    return head;
}

输入:
0 0 1 2 3 0 0 1 q
输出:
0 0 1 2 3 0 0 1
1 2 3 1

  • 54
    点赞
  • 248
    收藏
    觉得还不错? 一键收藏
  • 6
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值