线性表链式存储结构的特点是:用一组任意的存储单元存储线性表的数据元素(这组存储单元可以是连续的,也可以是比连续的)。
注:ElemType 表示为通用类型标识符,
习惯上用LinkList定义单链表,强调定义的是某个单链表的头指针;
用LNode *定义指向单链表中任意节点的指针变量。
1、 单链表的存储结构
typedef struct LNode
{
ElemType data;
struct LNode *next;
}LNode,*LinkList;
2、单链表的初始化
Status InitList(LinkList &L)
{//构建一个空的单链表L
L = new LNode;//生成新节点作为头结点,用头指针L指向头结点
L->next = NULL;//头结点的指针域置空
return OK;
}
3、单链表的取值
Status GetElem(LinkList L,int i,ElemType &e)
{//在头节点的单链表L中根据序号i获取元素的值,用e返回L中的第i个数据元素的值
p = L->next;//初始化,p指向首元结点,计数器j初值赋为1
j=1;
while(p&&j<i)//顺序域向后扫描,直到p为空或p指向第i个元素
{
p = p->next;
j++;
}
if(!p || j>i)//i值不合法i>n或i<=0
return ERROR;
e = p->data;
return OK;
}
该算法的平均时间复杂度为O(n);
4、单链表的按值查找
LNode *LocateElem(LinkList L,ElemType e)
{//在带头结点的单链表L中查找值为e的元素
p = L->next;//初始化,p指向首元结点
while(p &&p->data != e)//顺链域向后扫描,直到p为空或p所指结点的数据域等于
{
p = p->next;
}
return p;
}
平均时间复杂度为O(n);
5、单链表的插入
插入操作中合法的插入位置有n+1个。
Status ListInsert(LinkList &L,int i,ElemType e)
{//在带头结点的单链表L中第i个位置插入值为e的新节点
p = L;
j=0;
while(p && (j<i-1))
{//查找第i-1个结点,p指向该节点
p=p->next;
j++;
}
if(!p || (j>i-1) //i>n+1或i<1
return ERROR;
s = new LNode;//生成新节点*S
s->data = e;//将新节点*s的数据域置为e
s->next = p->next;//将结点*s的指针域指向结点a[i]
p->next = s;//将结点*p的指针域指向结点*s
return OK;
}
平均时间复杂度为O(n);
6、单链表的删除
Status LinkList(LinkList &L,int i)
{//在带头结点的单链表L中,删除第i个元素
p = L;
j=0;
while((p->next) && (j<i-1))
{//查找第i-1个结点,p指向该节点
p = p->next;
++j;
}
if(!(p->next) || (j>i-1))//当i>n或i<1时,删除位置不合理
return ERROR;
q = p->next;//临时保存被删除结点的地址以备释放
p->next = q->next;//改变删除结点前驱结点的指针域
delete q;//释放删除结点的空间
return OK;
}
平均时间复杂度为O(n);
6、创建单链表
根据插入结点的位置不同,链表的创建方法分为前插法和后插法。
6.1、前插法(逆序创建单链表法):前插法是通过将新节点逐个插入到链表的头部(头结点之后)来创建链表,每次申请一个新节点,读入相应的数据元素值,然后将新节点插入到头结点之后。
void CreateList_H(LinkList &L,int n)
{//逆位序输入n个元素的值,建立带头结点的单链表L
L = new LNode;
L->next = NULL;//建立一个带头结点的空链表
for(i=0,i<n;i++)
{
p = new LNode;//生成新节点*p
cin>>p->data;//输入元素值赋给新节点*p的数据域
p->next = L->next;
L->next = p;//将新节点*p插入到头结点之后
}
}
平均时间复杂度度为O(n);
6.2、后插法(正序建立单链表法):后插法是通过将新节点逐个插入到链表的尾部来创建链表。同前插法一样,每次申请一个新节点,读入相应的数据元素值。不同的是,为了使新节点能够插入到表尾,需添加一个为指针r指向链表的尾节点。
void CreateList_R(LinkList &L,int n)
{//正位序输入n个元素的值,建立带头结点的单链表L
L = new LNode;
L->next = NULL;//先建立一个带头结点的空链表
r = L;//为指针r指向头结点
for(i=0;i<n;i++)
{
p = new LNode;//生成新节点
cin>>p->data;//输入元素值赋给新节点*p的数据域
p->next = NULL;
r->next = p;//将新节点*p插入尾节点*r之后
r = p;//r指向新的尾节点*p
}
}