1.定义:
用一组任意的存储单元存储线性表的数据元素(这组存储单元可以是连续的,也可以是不连续的)。
2.单链表图解:
3.单链表的存储结构:
"递归定义:"
typedef struct LNode{
ElemType data; //结点的数据域
struct LNode * next; //结点的指针域
}LNode,*LinkList; //LinKlIST为指向结构体LNode的指针类型
结构体指针类型:LinkList 与 LNode *,两者本质上是等价的。
- LNode*p与LinkList p 的习惯用法:
- LinkList p强调定义的是某个单链表的头指针;
- LNode * p强调定义指向单链表中任意结点的指针变量。
4.operation:
①初始化
Status InitList(LinkList &L)
{
L=new LNode; //生成新结点作为头结点,用头指针L指向头结点
L->next=NULL; //头结点指针域置空
return OK;
}
②取值:(根据下标取得元素)
Status GetElem(LinkList L,int i,ElemType &e)
{
LNode *p=L->next; //p指向首元结点,
int j=1; //计数器赋值为1
while(p&&j<i) //当p不为空 且 输入的i值合法时
{
p=p->next; //p指向下一个结点
j++; //计数器++
}
if(!p||j>i) //p指向NULL 或 i值不合法
return ERROR;
e=p->data; //取第i个结点的数据域
return OK;
}O(n)
③查找:(根据元素值得到下标)
LNode *LocateElem(LinkList L,ElemType e)
{
//在头结点的单链表L中查找值为e的元素
LNode *p=L->next; //初始化,p指向首元结点
while(p&&p->data!=e) //顺链表向后遍历,直到p为空或者找到与e相等的结点时结束循环
{
p=p->next; //p指向下一个结点
}
return p; //查找成功返回e的结点地址p,查找失败p为NULL
}
④插入:
Status ListInsert(LinkList &L,int i,ElemType e)
{
//在带头结点的单链表L中第i个位置插入值为e的新结点
LNode *p=L;
int j=0;
while(p&&(j<i-1)) //查找第i-1个结点,p指向该结点
{
p=p->next;
j++;
}
if(!p||j>i-1)
return ERROR; //i>表长或者i<1
LNode *s=new LNode; //生产新结点*s
s->data=e; //将结点*s的数据域置为 e
s->next=p->next; //将结点*s的指针域指向结点
p->next=s; //将结点*p的指针域指向结点 *s
return OK;
}O(n)
⑤删除:
Status ListDelete(LinkList &L,int i)
{
//在带头结点的单链表L中,删除第i个元素
LNode *p=L;
int j=0;
while(p->next&&j<i-1) //查找第i-1个结点,p指向该结点
{
p=p->next;
j++;
}
if(!(p->next)||j>i-1)
return ERROR;
LNode *q=p->next; //临时保存被删结点以备释放
p->next=q->next; //改变删除结点的前驱结点的指针域
delete q; //释放被删除结点空间
return OK;
}O(n)
⑥创建单链表:
a.前插法创建单链表:
void CreateList_H(LinkList &L,int n)
{
L=new LNode; //先建立一个带有头结点的空链表
L->next=NULL;
for(int i=0;i<n;i++)
{
LNode *p=new LNode; //生成新结点*p
cin >> p->data; //输入元素赋值给*p的数据域
p->next=L->next;
L->next=p; //将新结点*p插入到头结点之后
}
} O(n)
b.后插法创建单链表:
void CreateList_R(LinkList &L,int n)
{
L=new LNode;
L->next=NULL;
LNode *r=L; //尾指针r指向头结点
for(int i=0;i<n;i++)
{
LNode *p=new LNode; //生成新结点
cin >> p->data;
p->next=NULL;
r->next=p;
r=p;
}
} O(n)
⑦清空
Status ClearList(LinkList & L){
// 将L重置为空表
LinkList p,q;
p=L->next; //p指向第一个结点
while(p) //没到表尾
{ q=p->next; delete p; p=q; }
L->next=NULL; //头结点指针域为空
return OK;
}
⑧销毁
Status DestroyList_L(LinkList &L){
LinkList p;
while(L)
{
p=L;
L=L->next;
delete p;
}
return OK;
}