当前位置:   article > 正文

链表家族(1)——单链表_给定一个单链表 l1→l2→ →ln 1→ln,请编写程序将链表重新排列为 ln→l1→

给定一个单链表 l1→l2→ →ln 1→ln,请编写程序将链表重新排列为 ln→l1→

总述

前面提到了链表,现在我们从最基础的来说起,来构建一个单链表

概念

最简单的链表。元素之间只有一个单独的指针链接。
打个比方,链表就像是一条链条,一个连着一个,我们要想找到其中某一个节点,即必须从链条头开始,一个一个往后找。
从这个比喻中可以看出链表的特殊性,我们随时都可以在链条的任何一个位置再加一个节点或删除一个节点。
一个连着一个非常安全,同样也是它最致命的弱点,只要有一个链断了,那么后面所有的节点就都没了,所以要格外注意连接问题。

实现

准备

首先我们得建立一种类型,用于描述链表中的每一个“链”。
“链”有两部分组成:一部分是主体,用来记录各种数据,另一部分则用来连接后面的“链”。

typedef struct LNode
{
    int num;            //学号
    char name[20];      //姓名
    int score;          //得分
    LNode *next;        //指向下一个链的指针
}LNode,*LinkList;       //LNode是类型名,LinkList是指向LNode类型的指针
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

建立空的链表

int InitList_L(LinkList &L)
{
    L=(LinkList )malloc(sizeof(LNode));
    L->next=NULL;
    return 0;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

这个子函数用于建立一个空链表,形参L以引用的形式传递会主函数,用来保存链表的表头空节点(用一个空白的节点使得整个链表的插入和删除更具一般性)。

插入

将e插入到t结点后面:

int ListInsert_L(LinkList &t, LNode e)
{
    LinkList E=(LinkList)malloc(sizeof(LNode)); //建立一个空的结点
    *E=e;                                      //将形参赋予空间中
    E->next=t->next;                            //插入操作(1)
    t->next = E;                                //插入操作(2)
    return 0;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

此操作相当于制作一个链,然后将t位置断开,再把新的链连进去。

删除

和插入同样的概念,将t位置断开,拿走一个链,然后将断开的链连上,最后再把拿走的链销毁。

int ListDelete_L(LinkList t)
{
    LinkList E=t->next;       //记录要删的结点的位置
    t->next=t->next->next;    //拿走要删的结点
    free(E);                  //销毁结点
    return 0;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

测长

从头到尾搜一遍,有多少个结点,便是多长。

int ListLength_L(LinkList L)
{
    int len;
    LinkList a=L;
    for(len=0;a->next!=NULL;len++,a=a->next);
    return len;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

如上,以a为迭代器,从头到尾遍历,如果到了链表结尾(无指向下一个的指针了)即找到了链表的长度。

返回第pos元素的指针

和测长原理差不多,只不过不是找到结尾罢了。

LinkList ListGetElem(LinkList L, int pos)
{
    for(;pos>0;pos--)L=L->next;
    return L;
}
  • 1
  • 2
  • 3
  • 4
  • 5

销毁链表

从头到尾销毁每一个链。
注意:每次销毁前,必须记录下下一个结点的位置!

void DestroyList_L(LinkList &L)
{
    int i;
    LinkList a=L,e;
    for(;a!=L;)
    {
        e=a;         //记录下当前结点
        a=a->next;   //将迭代器移位至下一个位置
        free(e);     //删除当前结点
    }
    free(L);         //销毁表头空结点
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

总结

效率分析

对于链表来说:
创建、插入、删除都是O(1)的效率,
测长、查找、销毁都是O(n)的效率。

说明

有了这些基本函数,就可以构建一个最简单的链表了。

声明

如果文章中有错误,欢迎指出,我会及时改正!

此文章为原创,如需转载,请注明转载地址!
http://blog.csdn.net/lliangw

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/笔触狂放9/article/detail/226782
推荐阅读
相关标签
  

闽ICP备14008679号