线性表的单链表

目录

1>.单链表的定义和表示

2>.单链表基本操作

1.初始化

2.取值

3.查找

4.插入

5.删除


1>.单链表的定义和表示

1.基本概念

特点:用一组任意的存储单元存储线性表的数据元素(存储单元可以连续,也可以不连续)。对数据元素ai,存储本身的信息和一个指示直接后继的存储位置,这两部分信息称为结点(存储数据元素信息的的数据域,存储直接后继存储位置的指针域

单链表(线性链表):链表的每个结点中只包含一个指针域。

注意:

1>>.首元结点:链表中存储第一个数据元素a1的结点

2>>.头结点:在首元结点之前加入的一个结点,其指针域指向首元结点

单链表中各个元素的存储位置都是随意的,每个元素的存储位置包含在其直接前驱结点的信息中。比如p->next=ai,则p->next->data=ai+1。单链表是非随机存取的存储结构,要取得第i个数据元素必须从头指针出发顺链进行寻找,也称为顺序存取的存储结构。 

单链表的定义:

typedef struct LNode
{
    ElemType data;        //结点的数据域
    struct LNode *next;   //结点的指针域
}LNode,*LinkList;         //LinkList为指向结构体LNode的指针类型

通常习惯用LinkList定义单链表,强调定义的是某个链表的头指针(定义LinkList L 则L为单链表的头指针)。用LNode *定义指向单链表中任意结点的指针变量(定义LNode *p则p为指向单链表某个结点的指针,*p代表该结点) 

2>.单链表基本操作

1.初始化

Status InitList(LinkList &L)
{
L=new LNode;      //生成新结点作为头结点,用头指针L只向头结点
L->next=NULL;     //头结点的指针域置空
return 0;
}

2.取值

Status GetElem(LinkList L,int i,ElemType &e)
{
P=L->next;      //p指向首元结点
j=1;
while(p&&j<i)   //向后查找,直到P为空或P指向第i个元素
{
p=p->next;      //p指向下一个结点
j++;
}
if(!p||j>i)     //i的值不合法
return 0;
e=p->data;      //取第i个结点的数据域
return 1;
}

算法的平均时间复杂度为O(n) 

3.查找

步骤:

1>>.指针p指向首元结点

2>>.从首元结点依次顺着链域next向下查找,直到p所指结点的数据域等于e

3>>.返回p

LNode *LocatedElem(LinkList L,ElemType e)
{
p=L->next;    //p指向首元结点
while(p&&p->data!=e)
p=p->next;
return p;     //查找成功返回为e的结点地址p
}

 算法的平均时间复杂度为O(n)

4.插入

基本思路:修改p的指针域,使其指向结点e,结点e的指针域指向结点b

插入前:

插入后:

步骤:

1>>.查找结点ai-1(上图的a所在方框),将指针p指向该结点

2>>.生成新结点s

3>>.将结点s的指针域指向ai(上图的b所在方框)

4>>.将结点p的指针域指向结点s

Status ListInsert(LinkList &L,int i,ElemType e)//带头结点的单链表
{
p=L;
j=0;
while(!p&&(j<i-1))
{
p=p->next;                         //查找第i-1个结点并P指向该结点
j++;
} 
if(!p||j>i-1)                      //i的值不合法
return 0;
s=new LNode;                       //生成新结点s
s->data=e;                         //将s的数据域设置为e
s->next=p->next;                   //将结点s的指针域指向结点a
p->next=s;                         //将结点p的指针域指向结点s
return 1;
}

算法的平均时间复杂度为O(n) 

5.删除

步骤:

1>>.查找结点ai-1(上图a所在的方框),指针p指向该结点

2>>.用q临时保存要删除结点ai(上图b所在的方框)的地址方便之后释放其空间

3>>.将结点p的指针域改向指向ai的直接后继结点(上图c所在的方框)

4>>.释放结点ai(上图b所在的方框)的空间

Status ListDelete(LinkList &L,int i)
{//带头结点的单链表L,删除第i个元素
p=L;
j=0;
while((p->next)&&(j<i-1))
{
p=p->next;                        //查找第i-1个结点,p指向该结点
j++;
}
if(!(p->next)||(j>i-1)      
q=p->next;                        //临时保存被删除结点的地址
p->next=q->next;                  //将p的指针域指向被删除结点的指针域
delete q;                         //释放删除结点的空间
return 1;
}

算法的平均时间复杂度为O(n) 

注意:删除算法中与插入算法中的循环条件有区别,因为插入操作中合法的插入位置有n+1个,而删除操作合法的删除位置只有n个。

我需要一个答案,也许美满,也许破碎,但是我不想半途而废。改变自己最快的方式,就是做你害怕的事。分享给大家一句话 “内心丰盈者,独行亦如众”——三毛《撒哈拉的故事》。

制作不易,希望多多关照,给个关注。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值