链式存储特点:
用一组任意的存储单元存储线性表的数据
存储单元可以是连续的,也可以是不连续的
结点:
存储数据元素信息的 数据域
存储直接后继存储位置信息的 指针域
head: 头指针 指向链表中第一个结点
tail 尾指针 0,有时表示为NULL
头节点:记录线性表的某些性质信息(如长度)
节点结构:
typedef struct link
{
char elem; //代表数据域
struct link * next; //代表指针域,指向直接后继元素
}Link;
我们习惯将结点中的指针命名为 next,因此指针域又常称为“Next 域”。
例如,创建一个存储 {1,2,3,4} 且无头节点的链表,C 语言实现代码为:
Link* initLink() {
int i;
//1、创建头指针
Link* p = NULL;
//2、创建首元结点
Link* temp = (Link*)malloc(sizeof(Link));
temp->elem = 1;
temp->next = NULL;
//头指针指向首元结点
p = temp;
//3、每创建一个结点,都令其直接前驱结点的指针指向它
for (i = 2; i < 5; i++) {
//创建一个结点
Link* a = (Link*)malloc(sizeof(Link));
a->elem = i;
a->next = NULL;
//每次 temp 指向的结点就是 a 的直接前驱结点
temp->next = a;
//temp指向下一个结点(也就是a),为下次添加结点做准备
temp = temp->next;
}
return p;
}
再比如,创建一个存储 {1,2,3,4} 且含头节点的链表,则 C 语言实现代码为:
Link *initLink()
{
int i;
Link *p=NULL; //头指针
Link *temp=(Link*)malloc(sizeof(Link)); //头节点
temp->elem=0;
temp->next=NULL;
p=temp; //头指针指向头节点
for(i=1;i<5;i++)
{
Link *a=(Link*)malloc(sizeof(Link)); //创建节点
a->elem=i;
a->next=NULL;
temp->next=a; //temp作为a的前驱节点
temp=temp->next; //temp指向下一个节点,也就是a,为下次添加做准备
}
return p;
}
链表的基本操作:
取第三个元素 :
e=p->data; 时间复杂度为 O(n)
插入元素: 在a与b之间插入元素x
s->next=p->next; //先将x指向b,避免丢失b的位置
p->next=s; //再将a指向x
删除元素b:
Node *q=p->link; //另位设置一个q指向b
p->link=q->link; //将pd的link指向q的link,
delete q; //撤销q代表的b
p-link=p->link->link; //这样也行,将a的后继结点直接指向c
单链表合并 :
void MergeList_L(LinkList &La,LinkList &Lb)
{
pa=La->link; //pa指向首元节点
pb=Lb->link; //pb指向首元节点
Lc=pc=La; //pc=Lc=La,头节点初始化
while(pa&&pb) //当两个单链表都没有连完
{
if(pa->data<=pa->data) //如果a的数据小于b的数据 ,则pc连上a
{
pc->link=pa; //第一次的pc此时为头节点,link指向pa
pc=pa; //将pc等于pa,便于下一次连接
pa=pa->link; //pa往下指
}
else //同理
{
pc->link=pb;
pc=pb;
pb=pb->data;
}
}
}