zoukankan      html  css  js  c++  java
  • 单链表的插入和删除

    近期,数据结构课上布置了运用单链表进行简单的插入和删除工作,今天,就在这里跟大家讲一下单链表的插入和删除是怎么弄的

    1.结点的定义

    typedef int ElemType;
    
    typedef int status;
    
     
    
    typedef struct LNode{
    
        ElemType data;
    
        struct LNode *next;
    
    }LNode, *LinkList;
    View Code

    这里的data就是我们链表里的数据元素了,next就是结点了也就是我们经常看到的p->next了。

    2,创建链表

    接下来我们讲讲创建链表,一个好的链表结构离不开创建函数的作用,其中,创建链表又分为头插法和尾插法,头插法:也就是每次放入元素的时候又把指针指向头指针,也称为尾插法,因为这样创建的链表输入的元素其实是逆序排列的,尾插法:首先需要设置一个尾结点,然后每次插入完了之后把指针指向尾结点,这样就能保证是顺序输入的了。

    头插法(倒插法):

    status CreateList_List(LNode*L,int n){
        int i,j;
        LNode *p;                                          //以同样的格式定义一个p指针,用它来进行元素的输入//
        L=(LinkList) malloc(sizeof(LNode));                //这里就是给我们的链表分配存储空间了//
        L->next = NULL;                                    //首先让L指向头指针//
        for(i=n;i>0;i--){
            p=(LinkList) malloc(sizeof(LNode));            //每输入一个数,就分配一个空间,这样可以有效的提高空间的利用率//
            printf("请输入该表的第%d个元素   :",i);
            scanf("%d",&j);
            p->data=j;                                     //这里就是我们的元素啦//
            p->next=L->next;                               //让我们的p指针指向头结点//
            L->next=p;                             //这里还不是太懂,就不误导大家了//
        }
        printf("
    ");
        return L;                                         //相信有同学注意到了我的这里和书上是不一样的,没错,是真的//
    }

    因为考虑到指针返回的问题,单链表想要返回地址的话是要用到二级指针的,二级指针太过麻烦了(其实是我不会啦),我在这里就用到了一个外部指针来接受我return的L,嘻嘻,是不是很聪明(反正我觉着还行),具体的大家会在我下面的主函数里面看到。。。

    尾插法,我还不熟练,就不拿非成品来忽悠大家了,之后我再补上。

    3.插入函数

    链表创建完成了,接下来就是它的插入功能了。

    status ListInsert_L(LNode*L,int i,int e){
        int j;
        LNode *p,*q,*s;                             //这里跟上面是一样的,就不多说了//
        p=L;                                        //地址传递//
        j=0;
        while (p&&j<i-1){p=p->next;++j;}            //这里用一个while循环,来找到我们的 i ,也就是插入的位置//
        if(!p||j>i-1) return ERROR;                 //然后如果输入的位置已经超过了链表的长度了,怎么办,这里会用一个if语句来判断,如果大于了链表的长度,那我们就直接退出插入程序了//
        s=(LinkList)malloc(sizeof(LNode));          //一样的哦//
        s->data=e;
        s->next=p->next;
        p->next=s;
        printf("插入后的线性表为:");               //这里考虑到都插入了,那怎么知道有没有成功呢,所以我们就输出来看一下//
        LNode *a=L->next;                     //定义一个节点让它等于头结点//
        while(a){
        printf("%d ",a->data);                //只有a指向的值不是NULL,也就是没有值,我们就持续输出//
        a=a->next;                               //输出完了一个元素,通过这个就可以让他指向下一个啦//
        }
        return L;                         //大家看到这里也是返回L哦,没错,这里也用到了外部指针哦//
    }

    4.删除函数

    加油加油,只差一个删除了

    status ListDelete_L(LNode*L,int i,ElemType *e){           
    
        int j;
        LNode *p,*q;
        p=L;
        j=0;
        while(p->next&&j<i-1){                                      //这里同样是用while循环来找到我们要删除的位置//
            p=p->next;
            ++j;
        }
        if(!(p->next)||j>i-1) return ERROR;                        //same again//
        q=p->next;                                        //怎么删除呢?//
        p->next=q->next;                                           //把你要删除的那个位置的节点删掉就好了,但是删掉之前,得把它的遗产解决了//
        e=q->data;                                      //也就是要把节点的指向改了,这样我们的链表就还是连在一起的哦,然后把删掉的元素赋值给e,留作纪念咯//
        free(q);                                                   //怎么删掉节点呢,没错,就是free掉它//
        printf("删除后的线性表为:");
        LNode *a=L->next;
        while(a){
        printf("%d ",a->data);
        a=a->next;
        }
    } 

    好啦,所有函数就搞定了,让我们下回再见.....呸呸呸,还有我们的核心,主函数呢

    5.主函数

    主函数作为调用子函数的一个集合体,怎么写就看大家心情了,但要提醒大家的是,必要的文字说明不能少,不然鬼知道你输的是什么

    int main()
    
    {
        int a,b,c,d,x,y;
        ElemType *z;                               //为什么这里冒出来这么一个玩意,你是不是这么想的,回头看看删除函数吧,第三个参数是怎么定义的//
        LNode *L,*s;                                          //没错,这里的s就是我们朝思墓想的外部指针了//
        printf("请输入链表的初始元素个数  :");                    //必要的文字说明哦//
        scanf("%d",&d);
        s=(CreateList_List(L,d));                              //就是这里,我们用s接收了创建函数的脑电波,,可以看到接下来的插入啊,删除啊,都变成s了//
        printf("初始线性表为  :");
        LNode *q=s->next;
        while(q){
        printf("%d ",q->data);
        q=q->next;
        }
        printf("
    是否要插入  1.是 2.否
    ");
        scanf("%d",&a);
        if(a==1){
            printf("请输入插入的元素  :
    ");
            scanf("%d",&c);
            printf("请输入插入的位置  :
    ");
            scanf("%d",&b);
            s=(ListInsert_L(s,b,c));                         //再次接收我们插入过了的信号//
            printf("
    插入成功,退出插入系统中....
    ");
        }
        else
            printf("
    退出插入系统中.....
    ");
        printf("
    是否要删除 1.是 2.否
    ");
        scanf("%d",&x);
        if(x==1){
            printf("请输入删除元素的位置  :");
            scanf("%d",&y);
            ListDelete_L(s,y,z);
            printf("删除成功,退出删除系统中....
    ");
        }
        else
            printf("退出删除系统中.....
    ");
        return 0;
    }

    感谢感谢,看到这里也不容易,如果大家发现我哪里有错,可以在评论区里面直接说哦,我会很虚心,超级虚心的接受的。

    本次分享到此结束,之后会不定期更新哦,谢谢大家!!!

  • 相关阅读:
    STL源码剖析:迭代器
    STL源码剖析:配置器
    [bzoj3940][Usaco2015 Feb]Censoring
    [bzoj2212][Poi2011]Tree Rotations
    [bzoj2733]永无乡&&[bzoj3545]Peaks
    挂个AC自动机
    [bzoj4237]稻草人
    莫比乌斯反演定理证明
    斜率优化dp学习
    备忘
  • 原文地址:https://www.cnblogs.com/tqdlb/p/11631452.html
Copyright © 2011-2022 走看看