单链表存储结构
typedef struct Node
{
int data;
struct Node *next;
}Node;
typedef struct Node* LinkList;
节点由存放数据元素的数据域和存放后继节点地址的指针域组成
一、单链表的创建
头插法
目的:创建长度为n的链表例如:7->6->5->4->3->2->1->NULL
实现:①创建L为头节点:数据域为空,指针域指向NULL作为头指针
②添加n个节点:创建结点指针p,每次创建申请空间生成一个新的节点
利用指针操作数据域的赋值。从头指针后开始插入,每次插入的结点为链表的第一个结点
void CreateListHead(LinkList &L,int n)
{
LinkList p;
L=(LinkList)malloc(sizeof(Node));
(L)->next=NULL;
for (int i = 0; i < n; i++)
{
p=(LinkList)malloc(sizeof(Node));
p->data=i+1;
p->next=(L)->next;
(L)->next=p;
}
}
因为每次按“顺序”插入的是第一个节点,所以链表数据是“倒序”的
尾插法
目的:创建长度为n的链表例如:1->2->3->4->5->6->7->8->9->10->NULL
实现:①创建L为头节点,赋给指针r,指针r作为游标
②添加n个节点:创建结点指针p,每次创建申请空间生成一个新的节点
利用指针操作数据域的赋值。从头指针后开始插入,每次插入的结点为链表的最后一个结点
③每次插入后把新插入的结点赋给游标r,标记最后一个结点的位置
④最后将r指向NULL作为结束
void CreateListTail(LinkList &L,int n)
{
LinkList p,r;
L=(LinkList)malloc(sizeof(Node));
r=L;
for (int i = 0; i < n; i++)
{
p=(LinkList)malloc(sizeof(Node));
p->data=i+1;
r->next=p;
r=p;
}
r->next=NULL;
}
因为每次按“顺序”插入的是最后一个节点,所以链表数据也是“顺序”的
二、单链表的读取
功能:读取链表中第i个数据的值
实现:
①创建p指向第一个结点,利用j作为结点的下标
②向后移动p,直到找到所在结点,若j>i或p为空说明链表没有第i个元素
③得到第i个数据的值
void GetElem(LinkList &L,int i)
{
int j=1;
LinkList p=L->next;
while (p&&j<i)
{
p=p->next;
++j;
}
if (!p||j>i)
{
cout<<"have not found this element!"<<endl;
return ;
}
int e=p->data;
cout<<e<<endl;
return ;
}
三、单链表的插入
功能:将数据e插入到链表第i个数据之后
实现:
①创建p指向第一个结点,利用j作为结点的下标
②向后移动p,直到找到所在结点,若j>i或p为空说明链表没有第i个元素
③生成新的节点add,将e赋值给add的数据域,先让add指向p的下一个节点,再让p指向add
void ListInsertAft(LinkList &L,int i,int e)
{
LinkList p=L->next;
int j=1;
while (p&&j<i)
{
p=p->next;
j++;
}
if(!p||j>i)
{
cout<<"结点不存在!"<<endl;
return ;
}
LinkList add=(LinkList)malloc(sizeof(Node));
add->data=e;
add->next=p->next;
p->next=add;
return ;
}
必须先让add指向p的下一个节点,再让p指向add。
若先让p指向add,则p的下一个节点就是add,add没办法指向原来p后的节点,相当于链表“断了”。
四、单链表的删除
功能:删除单链表中第i个元素
实现:
①创建p为头指针,利用j作为标记,j比p的下标大1
②向后移动p,直到找到所删除结点前一个节点,若j>i或p->next为空说明链表没有第i个元素
③创建q指向p之后的第一个结点(所删除的结点),再使p指向的下一个节点为q的下一个节点,即跳过q这个节点
④释放结点q的内存
void ListDelete(LinkList &L,int i)
{
LinkList p=L,q;
int j=1;
while (p->next&&j<i)
{
p=p->next;
j++;
}
if(!(p->next)||j>i)
{
cout<<"结点不存在!"<<endl;
return ;
}
q=p->next;
p->next=q->next;
cout<<q->data<<endl;
free(q);
return ;
}
五、单链表的整表删除
功能:删除整个链表
实现:
①创建p指向第一个结点,将p赋值给q
②先释放掉q的内存,再向后移动p,直到表尾
③使头指针L指向NULL,表中不再有数据元素
void ClearList(LinkList &L)
{
LinkList p,q;
p=L->next;
while (p!=NULL)
{
q=p;
p=p->next;
free(q);
}
L->next=NULL;
cout<<"删除成功!"<<endl;
}
六、显示链表中的数据
功能:显示所有数据
实现:创建p指向第一个结点,每次向后移动输出数据即可
void show(LinkList &L)
{
LinkList p=L->next;
while (p!=NULL)
{
printf("%d->",p->data);
p=p->next;
}
cout<<"NULL"<<endl;
return ;
}
总结
本篇介绍了对单链表的创建、插入、删除等操作。使用c++的指针对链式存储结构进行操作十分灵活,有牵一发而动全身的效果。
测试代码及运行实例
int main()
{
LinkList cr,me;
CreateListHead(cr,7);
show(cr);
CreateListTail(me,10);
show(me);
GetElem(cr,7);
GetElem(me,10);
ListInsertAft(cr,7,50);
show(cr);
ListDelete(cr,1);
show(cr);
ClearList(cr);
show(cr);
return 0;
}