一、链表
在链表存储中,每个结点不仅包含所存元素的信息,还包含元素之间逻辑关系的信息,如单链表中前驱结点包含后继结点的地址信息,这样就可以通过前驱结点中的地址信息找到后继结点的位置。
链表的特性:
- 不支持随机访问
- 支持存储空间的动态分配
- 链表中进行插入操作无须移动元素
二、 单链表
在每个结构中除了包含数据域外,还包含一个指针域,用以指向其后继结点。
- 带头结点的单链表中,头指针 head 指向头结点,头结点的值域不包含任何信息,从头结点的后继结点开始存储数据信息。头指针 head 始终不等于 NULL,head -> next 等于 NULL 的时候,链表为空。
- 不带头结点的单链表中的头指针 head 直接指向开始结点,当 head 等于 NULL 的时候,链表为空。
两者最明显的区别是,带头结点的的单链表中有一个结点不存储信息,只是作为标志,而不带头结点的单链表的所有结点都存储信息。
结构体定义
// 结构体定义
typedef struct LNode
{
int data;
struct LNode *next;
}LNode;
查找算法
// 查找算法:在单链表L中查找值为e的元素(带头结点)
LNode* findElem(LNode *C,int e)
{
LNode *p=C->next; // 结构体是指针,访问时用->
while(p!=NULL)
{
if(p->data==e)
return p; // 返回结点指针
p=p->next;
}
return p; // 返回NULL
}
插入算法
// 插入算法:往结点p的后面插入结点s
void insertElem(LNode *&p,LNode *&s)
{
s->next=p->next;
p->next=s;
}
删除算法
// 删除算法:删除结点p后面的结点
void delElem(LNode *&p)
{
q=p->next;
p->next=q->next;
free(q);
}
尾插法建立链表
// 尾插法建立链表:假设有n个元素存储在数组a中,用尾插法建立链表C
void createListR(LNode *&C