单链表的存储结构
//LNode表示一个单一的结点
//*LinkList表示头指针,指向一个单链表的头结点,头结点一般为空!
typedef struct LNode
{
ElemType data;
struct LNode *next;
}LNode, *LinkList;
初始化
Status InitList(LinkList *L)
{
/*
*L = (LNode *)malloc(sizeof(LNode));
*/
//头结点的data一般为空
(*L) = new LNode;
(*L)->next = NULL;
return OK;
}
取值
Status GetElem(LinkList L, int i, ElemType *e)
{
p = L->next; //第一个结点
j = 1; //计数器,初始化为1
//直到p为空或p指向第i个元素
while(p && j<i) //&& and
{
p = p->next;
j++;
}
if(!p || j>i)
{
return ERROR;
}
*e = p->data;
return OK;
}
查找
//这里返回的是一个结点指针
LNode *LocateElem(LinkList L, ElemType e)
{
p = L->next;
while(p && p->data!=e)
p = p->next;
return p;
}
插入
Status ListInsert(LinkList *L, int i, ElemType e)
{
p = *L; //p指向头结点
j = 0; //头结点的位置为0
//找到要插入位置的前一个结点,所以要i-1
while(p && (j<i-1))
{
p = p->next;
j++;
}
if(!p || (j>i-1))
return ERROR;
s = new LNode;
//p是要插入结点s的前一个结点
s->data = e;
s->next = p->next;
p->next = s;
return OK;
}
删除
Status ListDelete(LinkList *L, int i)
{
p = *L;
j = 0;
//避免出现空指针,p->next
/*
如若是p,比如对一个只有3个结点的链表,如果i=4,那么确实可以找到4之前的第3个结点p,但是p->next=NULL
q = p->next = NULL, q就没有next了,会造成后续程序失败
*/
/*
但是对于插入操作,i=4,即插入在末尾,找到4之前的第三个结点p,虽然新节点s = p->next = NULL,但是后续程序只会用到NULL
不会对NULL进行取值操作
*/
while((p->next) && (j<i-1))
{
p = p->next;
j++;
}
if(!(p->next) || (j>i-1))
return ERROR;
q = p->next;
p->next = q->next;
delete q;
return OK;
}
创建单链表——头插法与尾插法
//头插法
void CreateList_H(LinkList *L, int n)
{
*L = new LNode;
*L->next = NULL;
for(i=0;i<n;i++)
{
p = new LNode;
cin>>p->data; //输入新节点的data
//关键步骤,新节点的next指向头结点的下一个,然后头结点的next指向p
p->next = L->next;
*L->next = p;
}
}
//尾插法
void CreateList_T(LinkList *L, int n)
{
*L = new LNode;
*L->next = NULL;
//关键中间变量,永远指向新节点,即单链表的最末尾结点,初始化为头结点
s = *L
for(i=0;i<n;i++)
{
p = new LNode;
cin>>p->data;
s->next =p;
p->next = NULL;
s = p;
}
}