链式存储结构:
结构:
数据域 |
指针域 |
Data |
Next |
结点定义:
Typedef struct LNode
{
ElemType data;
Struct LNode *next;
}LNode,*LinkList;
头指针:LinkList即为头指针。本身一般不存储信息(也可存储长度等相关信息),指向第一个元素结点
头结点≠头指针 链表必须要头指针,但是不一定有头结点
头结点的好处:①方便操作和处理(对于第一个元素而言)。②空表和非空表操作统一
操作:
- 建表
- 头插法:将新结点插入到当前表头
头插法建立的数据顺序与读取的数据顺序相反。
LinkListCreat_Head(LinkList &L)
{
L=(LinkList) new LNode; //创建头结点
L->next=NULL; //初始化空链表
Int x;
Cin>>x;
While(x!=9999) //终止条件
{
S=(LinkList) new LNode; //创立新结点
S->data=x; //结点数据赋值
S->next=L->next; //新结点的后继指向尾部(NULL)
L->next=S; //头结点的后继指向新节点
Cin>>x; //获取下一个数据的值
}
Return L;
}
- 尾插法
LinkListCreat_Rear(LinkList &L)
{
L=(LinkList) new LNode; //创建头结点
LNode *s,*r=L; //r为表尾指针,指向表尾
Int x;
Cin>>x;
While(x!=9999) //终止条件
{
S=(LinkList) new LNode; //创立新结点
S->data=x; //结点数据赋值
r->next=s; //
r=s; //r指向新的表尾
Cin>>x; //获取下一个数据的值
}
r->next=NULL; //尾结点指针置空
Return L;
}
尾插法建立的数据顺序与读取的数据顺序一致。
②查找结点
1. 按序号
从第一个结点出发,顺指针next域逐个往下搜索,知道找到第i个结点,否则返回最后一个结点的指针域NULL。
LNode *GetElem_Loc(LinkList L, int i)
{
If(i==0) return L; //查找第0个节点(头结点),直接返回
LNode *P=L->next; //第一个结点赋给P
Int j=1; //用于计数
While(P&&j<i) //从第一个结点开始查找第i个结点(同时保证指向当前结点的指针不为空)
{
P=P-next;
J++;
}
Return P;
}
2.按值
LNode *GetElem_Data(LinkList, ElemType e)
{
LNode *P=L->nextg;
While(P!=NULL&&P->data!=e)
P=P->next; //遍历链表
Return P; //返回结果(没找到就是空)
}
③插入(按位置)
P=GetElem_Loc (L,i-1); //获取前驱指针
S->next = P->next; //将*S的指针域指向*P的后继结点
P->next=S; //令结点*S的指针域指向新插入的结点*S
④删除操作
P=GetElem_Loc(L,i-1); //获取被删除位置的前驱指针
Q=P->next; //辅助指针(指向被删除结点)
P->next=Q->next; //P指向结点的后继指向被删除节点的后继
Delete Q; //释放内存