什么是链式呢,链式表示与顺序表示的最大区别就是,元素的物理地址是否连续,在链式表示中元素的物理地址可能连续也可能不连续,各元素之间通过指针相连接。
单链表的定义和表示
线性表的链式存储结构的特点是:用一组任意的存储单元存储线性表的数据元素,(这组存储单元可以是连续的也可以是不连续的)。因此为了表示每个数据元素与后继数据元素之间的看逻辑关系,除了存储本身的信息外,还存储了一个指向本元素直接后继的元素的地址,由数据元素和指针构成的整体称为节点。它包含两个域一个是数据域另一个是指针域。所以由多个节点构成的表称为单链表。
注意:
一般情况下,为了处理方便,在单链表的第一个节点之前增加一个节点,称之为头结点。
头结点的作用:
1、便于首元节点的处理
2、便于空表和fei空表的统一处理
接下来我来介绍一下单链表基本操作的实现
首先来定义设置一个结构体
typedef struct Lnode{
int data; //数据域
linklist *next; // 指针域
} Lnode,*linklist;
注意:
这个结构体实际上是单链表中节点的组成成分。
1、单链表初始化
Status initlist(LNode* &L){
L=new Lnode; //生成新节点作为头结点,并把地址赋给L
L->next=NULL;
return OK;
}
2、单链表的取值
Status getelem(Lnode* L,int i,int &e){
int k=0; //记录节点个数
Lnode* p;
p=L->next;
while(p){
k++;
if(k==i){
e=p->data;
return OK;
}
p=p->next;
}
return ERROR;
}
3、单链表中某个元素的查找
Lnode* findelem(Lnode* L,int e){
Lnode* p;
p=L->next; //初始化p指向首元节点
while(p){ //顺着单链表向后访问节点
if(p->data==e) //如果找到e则返回e的地址
return p;
p=p->next;
}
return ERROR;
}
4、单链表的插入
Status insertlist(Lnode* &L,int i,int e){
Lnode p,q;
q=new Lnode; //创建一个节点来存储e
q->data=e;
q->next=NULL;
int k=1;
p=L->next;
while(p&&k<i-1){ //遍历单链表L找到第i-1个元素或p为NULL时结束遍历
p=p->next;
k++;
}
if(!p)
return ERROR;
q->next=p->next; //如果找到第i-1个元素将e插入后边
p->next=q;
return OK;
}
5、单链表的删除
Status deletelist(Lnode* &L,int i){
LNode p,q;
p=L->next;
int k=1;
while(p||k<i-1){ //遍历单链表L寻找第i-1个元素
p=p->next;
k++;
}
if(!p)
return ERROR;
q=p->next; //如果找到删除第i个元素
p->next=q->next;
delete q; //将第i个元素空间释放
return OK;
}
介绍完单链表的基本操作之后,我来介绍一下单链表的创建
单链表的创建分为两种方式
1、头插法:顾名思义就是在头结点之后插入一个节点
2、尾插法:与头插法相反,在单链表的尾部进行插入节点
注意:
将节点用头插法插入到单链表时,访问插入的元素时,元素顺序与插入到单链表之前的数据元素的顺序相反。
比如创建由n个节点的单链表
头插法
void insertelem(Lnode* &L,int n){
L=new Lnode;
L->next=NULL;
for(int i=1;i<=n;i++){
Lnode *s;
s=new Lnode; //创建一个新的节点,用来存储数据
cin>>s->data;
s->next=L->next;
L->next=s;
}
return ;
}
尾插法
void insertelem(Lnode* &L,int n){
L=new Lnode;
L->next=NULL;
Lnode* p;
p=L; //创建一个p节点为了表示L的尾节点,便于进行尾插法
for(int i=1;i<=n;i++){
Lnode* s;
s=new Lnode;
cin>>s->data;
s->next=p->next;
p->next=s;
p=s;
}
return ;
}
其实单链表并不难,只要你理解指针,单链表就是小意思了,对单链表的介绍就到这里了。