线性表链式存储结构

其特点是用一组任意的存储单元存储数据元素,这组存储单元可以存在内存中未被占用的任意位置。出来存储本身的信息外,还需要存储一个指示其直接后继的存储位置的信息。这连个位置分别叫做:数据域 和 指针域。这两部分信息组成数据元素称为结点(Node)。该种结构只包含一个指针域,因此叫做单链表。

【数据结构算法】线性表(二):链式存储结构_结点

单链表存储结构代码描述

typedef struct Node
{
    ElemType data;     //数据域
    struct Node *Next; //指针域
}Node;
typedef struct Node* LinkList;

单链表中头结点和头指针的异同

单链表中,头结点和头指针有较大差别,理解它俩的区别对后续理解单链表的各项操作至关重要。
头指针是指链表指向的第一个结点指针,若链表有头结点,则是指向头结点的指针。头指针通常就是指针变量的名字(这一点很重要)。无论链表是否为空,头指针都不为空。
【数据结构算法】线性表(二):链式存储结构_时间复杂度_02

线性表链式存储结构下查找,插入,删除数据

读取数据(时间复杂度o(n))

在线性表的顺序存储结构中想查找一个元素的存储位置是很容易的,但在单链表中,由于我们并不能够知道第i个位置在哪,我们需要从第一个结点开始挨个查找。

//用e返回链表中第i个位置的值
GetElem(LinkList L,int i, ElemType *e)
{
    int j;
    LinkList p;   //链表名表示的是头指针,指向头结点

    p = L->next;
    j = 1;
    //直到p为空或者找到第i-1(也就是i个元素停止,此时p指向的就是第i个元素)
    while( p && j<i)
    {
        p = p->next;
        ++j;
    }
    if (!p || j>i)
    {
        return ERROR;
    }

    *e = p->data;
    retrun OK;
}

插入数据(时间复杂度o(n))

在单链表中,由于我们并不能够知道第i个位置在哪,我们需要从第一个结点开始挨个查找,再执行插入。

//在第i个位置之前插入新的数据元素e
ListInsert(LinkList *L, int i, ElemType e)
{
    int j;
    LinkList p, a;

    p = *L;
    j = 1;
    //这两部分和上面查找是一样的
    while( p && j<i)
    {
        p = p->next;
        ++j;
    }
        if (!p || j>i)
    {
        return ERROR;
    }

    s = (LinkList)malloc(sizeof(Node));
    s->data = e;
    //因为此时p指针指向的是当前位置,所以将p->next给被插入结点ss->next,然后将s给p->next;
    s->next = p->next;
    p->next = s;

    return Ok;
}

删除数据(时间复杂度o(n))

在单链表中,由于我们并不能够知道第i个位置在哪,我们需要从第一个结点开始挨个查找,再执行删除。

ListDelete(LinkList *L, int i, ElemTpye *e)
{
    int j;
    LinkList p, q;
    p = *L;
    j = 1;

    //这两部分和上面查找是一样的
    while( p && j<i)
    {
        p = p->next;
        ++j;
    }
        if (!p || j>i)
    {
        return ERROR;
    }

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

    //这里确实是删除q的,因为此时q正好空出来啦
    *e = q->data;
    free(q);

    return OK;

}

线性表顺序和链式存储的效率PK

如果我们不知道第i个元素的指针位置,单链表数据结构在插入和删除操作上,是没有太大优势的。单如果我们希望从第i个位置开始,插入连续10个元素,这对于顺序存储结构意味着,没插入一次都要移动n-i个位置,所以每次都是o(n),而链表只是第一次找i位置时要o(n),而之后都是0(1)就行了。所以比如说一个游戏中人物的装备,这种情况下单链表的优势就比较明显了,因为这种情况需要频繁的插入。

单链表结构和顺序存储结构优缺点

存储分配方式
  • 顺序存储结构用一段连续的存储单元依次存储线性表的数据元素。

  • 单链表采用链式存储结构,用一组任意的存储单元存放线性表的元素。

时间性能
查找
  • 顺序o(1)

  • 单链表o(n)

插入和删除
  • 顺序存储结构需要平均移动表长一半的元素,时间复杂度为0(n).

  • 单链表在计算出某位置的指针后,插入和删除时的时间复杂度为o(1).

空间性能
  • 顺序存储结构需要预先分配内存空间,分大了浪费,分小了不够用。

  • 单链表不需要分配内存空间 ,元素个数不受限制。