线性表的链式表示与实现
*线性表的链式存储结构的特点是用一组任意的存储单元存储线性表的数据元素(这组存储单元可以是连续的,也可以是不连续的)。*因此,为了表示每个数据元素ai与其直接后继数据元素ai+1之间的逻辑关系,对数据元素ai来说,除了存储其本身的信息之外,还需存储一个指示其直接后继的信息(即直接后继的存储位置)。这两部分信息组成数据元素a,的存储映像,称为结点(node)。它包括两个域:其中存储数据元素信息的域称为数据域;存储直接后继存储位置的域称为指针域。指针域中存储的信息称做指针或链。n个结点(ai(1≤i≤n)的存储映像)链结成-一个链表,即为线性表(a1 ,a2 ,…,an)的链式存储结构。又由于此链表的每个结点中只包含一个指针域,故又称线性链表或单链表。
//---线性表的单链表的存储结构---
typedef struct LNode{
ElemType data;
struct LNode *next;
}LNode,*Linklist;
如果L是Linklist型的变量,L是单链表的头指针,它指向表中的第一个节点。
假设P为指向当前结点的指针,p->next则为指向下一个结点数据元素的指针。若p->data=a1,则p->next->data=a2.
//函数GetElem在单链表的实现
Status GetElem_L(LinkList L,int i,ElemType &e){
//L为带头结点的单链表的头指针
//当第i个元素存在时,其值赋给e并返回OK,否则会返回ERROR
p=L->next;j=1; //初始化,p指向第一个结点,j为计数器
while (p&&j<i){ //顺指针向后查找,知道p指向第i个元素或者p为空
p=p->next;++j;
}
if(!p||j>i) return ERROR; //第i个元素不存在
e=p->data; //取第i个元素
return OK;
}
单链表的删除和插入操作及实现
为插人数据元素x,首先要生成一个数据域为x的结点,然后插入在单链表中。根据插人操作的逻辑定义,还需要修改结点a中的指针域,令其指向结点x,而结点x中的指
针域应指向结点b,从而实现3个元素a、b和x之间逻辑关系的变化。假设s为指向结点x的指针,则上述指针修改用语句描述即为:
s->next=p->next;p->next=s;
反之,在进行删除操作时(设b为删除对象)在单链表中实现元素a、b、c之间逻辑关系的变化,仅仅修改结点a中的指针域即可。
p->next=p->next->next;
//ListInsert和ListDelete在单链表的实现
Status ListInsert_L(LinkList &L,int i,ElemType e){
//在带头结点的单链表L中第i个位置之前插入元素e
p=L;j=0;
while(p&&j<i-1)
{
p=p->next;
++j; //找寻第i个结点
if(!p||j>i+1) //i小于或者大于表长+1
return ERROR;
s=(LinkList)malloc(sizeof(LNode));
s->data=e;
s->next=p->next;
p->next=s;
return OK;
}
Status ListInsert_L(LinkList &L,int i,ElemType &e){
//在带头结点的单链表L中,删除第i个元素,并由e返回其值
p=L;j=0;
while(p->next&&j<i-1)
{
p=p->next;
++j; //找寻第i个结点
if(!p||j>i-1) //删除位置不合理
return ERROR;
q=p->next;
p->next->next=q->next;
e=q->next;
free(p);
return OK;
}