码迷,mamicode.com
首页 > 其他好文 > 详细

单链表的读取、插入与删除

时间:2017-09-17 11:48:36      阅读:141      评论:0      收藏:0      [点我收藏+]

标签:数据结构   单链表   

  链表是由一个个结点构成,而每一个结点都是由存储数据的数据域以及存储下一个结点地址的地址域两部分构成。

  链表的一大优点就是,可以在任意两个数之间毫无限制的插入无限多的数据。在很多时候,我们都需要对数据做个查找工作,就比如,一个班的同学去上课,结果老师发现人数不对,于是就开始点名,点到后来发现某某某同学没有到,这就是典型的数据查找。那么如何实现对链表的数据元素的查找呢?

比如,我想知道链表的第5个元素的值是多少,我应该怎么做呢?由于,链表是依靠地址来查找数据的,那比如说链表的第一个结点的数据域中保存了某一个元素值,而它的地址域中则保存了下个结点的地址,也就是说,每一个结点的地址都被保存在上一个结点的地址域中。那么,很明显,第5个元素的地址被保存在了第4个元素的地址域中,那么,也就是说,我想知道第5个元素在哪个位置,我首先得知道第四个元素在什么位置,那么以此类推,就需要知道第1个元素的存储位置,也就是说,我想要知道第5个元素的存储的位置,我首先就得从链表的头部开始查找。那么,我想知道链表的第i个元素的位置,我还是得从表头开始查起。很明显,想要知道第i个元素的位置,就需要申明一个循环变量j以及一个指针变量p来遍历链表。

技术分享

  当然,想要查找链表的元素,前提还得是链表不能为空,如果为空,那元素怎么可能查得到。这就好比,一个班的同学都没去上课,那老师还用的着点名吗,根本就没有点名的必要性了。

那么,查找单链表的一个元素,代码如下:

Status GetElem ( LinkList L, int i, ElemType e *e )
{
    int j;
    LinkList p;
    
    j = 1;
    p = L->next;
    while ( p != NULL && j < i ){
        
        p = p->next;   //p指向下一个结点
        ++j;
    
    }
    
    if ( p == NULL || j > i )
    return ERROR;
    
    *e = p->data;

}

  接下来,就是关于单链表的元素插入了。假设,一个链表有5个元素,也就是它有1~5这五个结点,那么我想在第4个结点之前插入一个新的元素,那我该怎么做呢?也就是说,这个元素我会插入在第3和第4个元素之间。很明显的一点就是,第4个结点的地址保存在第3个结点的后继指针中,那么,我想插入这个结点s,那岂不是我首先要把第4个结点的地址保存下来,也就是说我首先要向第3个结点索要第4个结点的地址,然后,再把s的地址给第3个结点p。

代码如下:

s->next = p->next;
p->next = s;

  因为,之前我们是假设有5个元素,并且是假设在第4个元素之前插入数据,那假设我要在第6个元素之前插入数据,那么怎么办呢?很多人就说了,这不可能的,因为,一共就5个数据,你怎么插入在第6个元素之前,你这不是扯淡吗。没错,但是,程序并不知道,如果,我们从键盘输入的是第6个数据,那么,毫无疑问的程序就会出现bug。所以,我们在做元素的插入之前,我们的判断插入的位置合不合理。如果不合理,那么我们就返回一个ERROR值。代码如下:

Status ListInsert ( LinkList *L, int i, ElemType e )
{
    int j;
    LinkList p;
    
    p = *L;
    j = 1;
    while ( p != NULL && j < i ){
    
        p = p->next;
        ++j;
    }
    
    if ( p == NULL || j > i )
    return ERROR;
    
    s = ( LinkList ) malloc ( sizeof ( struct Node ) );  //动态申请一个结点
    s->data = e;
    s->next = p->next;
    p->next = s;
    
    return OK;

}

  最后,就是单链表元素的删除操作。与元素的插入操作类似,我们在删除之前要判断它删除点是否有问题,如果删除点有问题,那么就返回一个ERROR。

  那么,我们应该如何删除一个结点元素呢?假设我们仍然有5个结点元素,现在我们想要删除第3个结点的元素。那么我们应该如何做呢?首先,我们很清楚的是,第3个结点的后继指针中保存着第4个结点的地址,如果,删除第3个结点,那么岂不是第4个结点的地址也跟着丢失了,那岂不是这根链表就断开来了。所以,在删除第3个结点之前,就得把第3个结点的后继指针中的值保存下来。然后,将第3个结点的地址保存在第2个结点的后继指针中。代码如下:

q = p->next;
p->next = q->next;

其实,以上两条语句可以用一条语句来代替,

p->next = p->next->next;

  最后,删除了结点之后,还得释放该结点。

代码如下:

Status ListDelete ( LinkList *L, int i, ElemType *e )
{
    int j;
    LinkList p;
    LinkList q;
    
    p = *L;
    j = 1;
    while ( p != NULL && j < i ){
        
        p = p->next;
        ++j;
    }
    
    if ( p == NULL || j > i )
    return EEROR;
    
    q = p->next;
    p->next = q->next;
    
    free ( q );
    
    return OK;

}

到这里,基本上,对单链表的插入,删除,以及元素的获取就差不多了。事实上,对单链表的操作并不复杂,只要,对几个关键数据进行预先判别,那么,出现bug的几率就会降低很多。

本文出自 “梵高说我脑子有病” 博客,请务必保留此出处http://chen0547.blog.51cto.com/12489941/1965926

单链表的读取、插入与删除

标签:数据结构   单链表   

原文地址:http://chen0547.blog.51cto.com/12489941/1965926

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!