单链表的删除操作

【问题描述】

设有头结点单链表,实现单链表删除。

【输入形式】

第一行输入N,M;N表示单链表表长,M表示执行M次删除;

第二行输入N个整数,建立有头结点单链表;

接着输入M个整数,每个整数表示删除结点的位置(位序)。

【输出形式】

若删除成功,输出删除结点的关键字值;若删除不成功,则输出error。

最后输出执行M次删除后的单链表。

【样例输入】

5  3

10 20 30 40 50

2

5

4

【样例输出】

20

error

50

10 30 40

线性链表的删除:是指删除链表中的第 i 个结点,此时,链表中删除位置前后的结点之间的逻辑关系发生变化。因此,必须通过修改删除位置之前的结点指针指向才能实现。

  和插入算法一样。删除过程首先需要寻找删除结点的前一个结点位置,再通过修改结点的指针域完成删除操作。

单链表的删除算法:int deleteList(LinkList head, int pos ,ElemType *e)

基本删除算法:实现对单链表pos位置的结点进行删除,并通过参数*e,返回删除结点的关键字值。

此处注意:

(1)pos表示结点在链表中的位序;删除时需要判断位置的合法性,注意左右两个边界的判断。(2)参数*e表示将删除结点的值放入指定的存储单元,因此该参数为指针类型,表示存放的地址。函数调用时,实参一定是一个地址。

int deleteList(LinkList head, int pos ,ElemType *e)
{
    if(pos<1)
    {
        printf("error\n");
        return 0;
    }
    LNode* p=head;
    int i;
    for(i=1;i<pos&&p->next!=NULL;i++)     //寻找插入位置
        p=p->next;
    {
        if(p->next==NULL||i>pos)     //插入位置不正确返回失败
        {
            printf("error\n");
            return 0;
        }
    LNode* q=p->next;     //修改结点的指针域
    p->next=q->next;
    printf("%d\n",q->data);     //返回删除结点的值
    free(q);     //释放删除结点的储存空间
    }
    return 1;
}

带入完整代码并运行,查看结果:

#include<stdio.h>
#include<stdlib.h>
typedef  int ElemType;
typedef struct LNode
{
    ElemType data;
    struct LNode *next;
}LNode,*LinkList;

LinkList initList();
int insertList(LinkList head, int pos, ElemType e);
int deleteList(LinkList head, int pos ,ElemType *e);
void printList(LinkList head);
//初始化
LinkList initList()
{
    LNode* head;
    head=(struct LNode*)malloc(sizeof(struct LNode));
    if(!head)return NULL;
    head->next=NULL;
    return head;
}
//插入
int insertList(LinkList head, int pos, ElemType e)
{
    if(pos<1)return 0;
    LNode* p=head;
    int i;
    for(i=1;i<pos;i++)
    {
        if(p->next==NULL)return 0;
        p=p->next;
    }
    LNode* pnew;
    pnew=(LinkList)malloc(sizeof(LNode));
    pnew->data=e;
    pnew->next=p->next;
    p->next=pnew;
    return 1;
}
//删除
int deleteList(LinkList head, int pos ,ElemType *e)
{
    if(pos<1)
    {
        printf("error\n");
        return 0;
    }
    LNode* p=head;
    int i;
    for(i=1;i<pos&&p->next!=NULL;i++)
        p=p->next;
    {
        if(p->next==NULL||i>pos)
        {
            printf("error\n");
            return 0;
        }
    LNode* q=p->next;
    p->next=q->next;
    printf("%d\n",q->data);
    free(q);
    }
    return 1;
}
//输出
void printList(LinkList head)
{
    LNode* p=head;
    while(p->next)
    {
        p=p->next;
        printf("%d ",p->data);
    }
    return;
}
int main()
{
    LinkList head;
    ElemType e;
    int i,n,m,pos;
    scanf("%d%d",&n,&m);
    head=initList();
    for(i=0;i<n;i++)
    {
        scanf("%d",&e);
        insertList(head,i+1,e);
    }
    //补充代码:执行M次删除,并输出删除后的链表
    for(i=0;i<m;i++)
    {
        scanf("%d",&pos);
        deleteList(head,pos,NULL);
    }
    printList(head);
    return 0;
}


运行结果如下:

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值