数据结构之链式线性表


About:链式线性表

链式线性表的数据存储方式不同于顺序链式表。由于它的数据元素是存储在任意的单元空间(可以连续,也可非连续),所以它的存,取数据操作就不必受“牵一发而动全身”的罪。我们将一个数据元素存储的空间称为数据域,其直接后继存储空间称为指针域,二者统称为一个结点。各结点就可连成具有**“一对一”关系的链表。因该结点只含有一个指针域,所以我们可称该链表为线性链表或单链表**。

单链表的初始化

在单链表中,我们用头指针指示链表中第一个结点的存储位置,由于最后一个结点已无后继,所以最后一个结点的指针为‘’空“(NULL)。在算法实现中,多数情况下我们都用一个头结点顶替第一个结点的位置,这样在后续的存,取操作中我们就无需改变头指针的指向了。(头结点为一个数据域无需存储信息的结点)

4.png

由此我们来初始化一下单链表:

typedef struct LNode{
    ElemType data;
    struct LNode *next;
}LNode,*LinkList;

void CreateList_L(LinkList *L,int n)      //n为将要建立的结点数目
{
    *L=(LinkList)malloc(sizeof(LNode));
    (*L)->next=NULL;
    int i; LinkList p;
    for(i=n;i>0;--i)
    {
        p=(LinkList)malloc(sizeof(LNode));
        scanf("%d",&p->data);
        p->next=(*L)->next;			//重点代码
        (*L)->next=p;
    }
}

这里我们采用的是逆向动态生成单链表,即从表尾到表头逐个初始化新的数据元素,为什么这样玩呢,后面章节会引用到。

获取指定位序下的元素

因单链表没有随机存取的特点,所以当我们想要得到具体位序下的元素时,我们只能从第一个结点出发,依次寻找到该位序下的元素。具体算法如下:

Status GetElem_L(LinkList L,int i,ElemType *e)
{
    LNode *p=L->next; int j=1;
    while(p&&j<i)
    {
        p=p->next;
        ++j;
    }
    if(!p||j>i) return ERROR;
    *e=p->data;
    return OK;
}

单链表的插入和删除

单链表既然不用忍受**“牵一发而动全身”**的罪,那么它是如何进行插入和删除操作的呢,我们来看看吧。

插入操作

未命名文件 (2).png

由上图可知,在插入结点时,我们需要进行以下两个关键性步骤:

  • S->next=P->next
  • P->next=S

注意这两个步骤不能互换顺序,否则会造成S指针紊乱。

由上两条特征,算法实现如下:

Status ListInsert_L(LinkList L,int i,ElemType e)
{
    LNode *p=L,*s=NULL; int j=0;
    while(p&&j<i-1)
    {
        p=p->next;
        ++j;
    }
    if(!p||j>i-1) return ERROR;
    s=(LinkList)malloc(sizeof(LNode));
    s->data=e;  
    s->next=p->next;	p->next=s;			//重点代码
    return OK;
}

这里j=0时,P指向的是头结点

删除操作

未命名文件 (3).png

由上图可知,在删除结点时,我们只需跳过待删结点方可:

  • P->next=P->next->next或P->next=Q->next
  • free(Q)

由上两条特征,算法实现如下:

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

以上代码,我们为保证算法的健壮性,也附增了许多条件,大家细品。

In the end:

这里,我们采用的是以结点的方式来描述单链表。其实,单链表也可用一维数组进行描述。此类链表我们称为静态链表。但静态链表的算法实现过于冗杂,且这种存储方式,后面的数据结构也会涉及到,这里就不详解了。


传送门: http://adolesce.cn/archives/6.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值