1、链式存储定义
为了表示每个数据元素与其直接后继元素之间的逻辑关系,每个元素除了存储本身的信息外 ,还需要存储指示其直接后继的信息。
2、链式存储逻辑结构
n个结点链接成一个链式线性表的结构叫做链表,
当每个结点中只包含一个指针域时,叫做单链表。
3、链表的基本概念
表头结点
链表中的第一个结点,包含指向第一个数据元素的指针以及
链表自身的一些信息;
数据结点
链表中代表数据元素的结点,包含指向下一个数据元素的指
针和数据元素的信息;
尾结点
链表中的最后一个数据结点,其下一元素指针为空,表示无
后继元素;
4、单链表示例图
5、表头结点、数据结点 在C中的实现
表头结点:
/*
LinklistNode 为一个结构体,里面只包含一个指针,用于指向下一个元素
*/
typedef struct _struct_linklist
{
LinklistNode header;
int length;
}TLinklist;
/*LinklistNode 定义*/
typedef struct _struct_linklistnode LinklistNode;
struct _struct_linklistnode
{
LinklistNode *next;
};
数据结点:
typedef struct _struct_value
{
/*LinklistNode 结点用于保存下一个元素地址信息*/
LinklistNode node;
int value;
}Value;
6、插入元素操作
/*
该方法用于向一个线性表list的pos位置处插入新元素node
返回值为1表示插入成功,0表示插入失败
pos表示插入的位置,从0开始计数
*/
int List_Insert(Linklist* list, LinklistNode* node, int pos)
{
int iret = 1;
TLinklist *tlist = (TLinklist*)list;
iret = iret && (list != NULL) && (node != NULL) && (pos >= 0);
if(iret)
{
/*
判断插入的位置是否已经大于了当前链表长度,如果是,则修正插入位置为链表最后
可用本代码替换:pos = pos > tlist->length ? tlist->length:pos;
*/
if(pos > tlist->length)
{
pos = tlist->length;
}
/*current 指向了头结点的LinklistNode 成员*/
LinklistNode *current = (LinklistNode*)tlist;
for(int i = 0; (i<pos) && (current->next != NULL); i++)
{
current = current->next;
}
//插入元素
node->next = current->next;
current->next = node;
//改变链表长度
tlist->length++;
}
return iret;
}
7、删除元素操作
/*
该方法用于删除一个线性表list的pos位置处的元素
返回值为被删除的元素,NULL表示删除失败
*/
LinklistNode* List_Delete(Linklist* list, int pos)
{
LinklistNode *node = NULL;
TLinklist *tlist = (TLinklist*)list;
if(tlist != NULL)
{
/*确保要删除的位置合法*/
if((pos>=0)&&(pos < tlist->length))
{
/*current指向了头结点的LinklistNode成员*/
LinklistNode *current = (LinklistNode*)tlist;
for(int i = 0; (i<pos)&&(current->next != NULL);i++)
{
current = current->next;
}
/*删除元素*/
node = current->next;
current->next = node->next;
/*改变被删除元素的next指针值*/
node->next = NULL;
//改变元素个数
tlist->length--;
}
}
return node;
}
8、获取元素操作
/*
该方法用于获取一个线性表list的pos位置处的元素
返回值为pos位置处的元素,NULL表示获取失败
*/
LinklistNode* List_Get(Linklist* list, int pos)
{
LinklistNode *node = NULL;
TLinklist *tlist = (TLinklist*)list;
if(tlist != NULL)
{
/*判断位置是否合法*/
if((pos>=0) && (pos < tlist->length))
{
/*node指向了头结点的LinklistNode成员*/
node = (LinklistNode*)tlist;
/*当移动pos-1次后,node指向了要获取结点的前一个结点,而实际要获取的结点是当前结点的next,所以这里循环条件设置为i<=pos
*/
for(int i = 0; (i <= pos) &&(node->next != NULL);i++)
{
node = node->next;
}
}
}
return node;
}
9、完整源码下载
文件名:linklist-1.0.tar.gz
链接: http://pan.baidu.com/s/1hqjFjJu 密码: xhn8
文件名:linklist-1.1.tar.gz
链接: http://pan.baidu.com/s/1c0q92Bu 密码: stag
说明:次版本修复List_Get()函数,在链表为空是返回了链表头地址,新的实现如上所示!
编译步骤:
0.1 解压缩:tar -zxvf linklist-1.1.tar.gz
0.2 进入目录:./configure
0.3 生成Seqlist:make
0.4 运行程序:./Linklist