链表(Linked list)是一种常见的基础数据结构,是一种线性表,但是并不会按线性的顺序存储数据,而是在每一个节点里存到下一个节点的指针(Pointer)。由于不必须按顺序存储,链表在插入的时候可以达到O(1)的复杂度,比另一种线性表顺序表快得多,但是查找一个节点或者访问特定编号的节点则需要O(n)的时间,而顺序表相应的时间复杂度分别是O(logn)和O(1)。
使用链表结构可以克服数组链表需要预先知道数据大小的缺点,链表结构可以充分利用计算机内存空间,实现灵活的内存动态管理。但是链表失去了数组随机读取的优点,同时链表由于增加了结点的指针域,空间开销比较大。
使用链表结构可以克服数组链表需要预先知道数据大小的缺点,链表结构可以充分利用计算机内存空间,实现灵活的内存动态管理。但是链表失去了数组随机读取的优点,同时链表由于增加了结点的指针域,空间开销比较大。
在计算机科学中,链表作为一种基础的数据结构可以用来生成其它类型的数据结构。链表通常由一连串节点组成,每个节点包含任意的实例数据(data fields)和一或两个用来指向明上一个/或下一个节点的位置的链接("links")。链表最明显的好处就是,常规数组排列关联项目的方式可能不同于这些数据项目在记忆体或磁盘上顺序,数据的访问往往要在不同的排列顺序中转换。而链表是一种自我指示数据类型,因为它包含指向另一个相同类型的数据的指针(链接)。链表允许插入和移除表上任意位置上的节点,但是不允许随机存取。链表有很多种不同的类型:单向链表,双向链表以及循环链表。
以上摘自wiki.
本文是基于C的链表实现,包括表的创建、判断、插入、查找、删除等一些基本的操作。
以下是经过编译通过实现的代码:
linklist.c
#include <stdio.h>
#include <stdlib.h>
typedef int datatype; //定义类型
typedef struct _node_ //定义数据节点
{
datatype data; //节点数据域
struct _node_ *next; //节点指针域,存放下个节点的地址
} linknode, *linklist;
linklist CreateLinklist() //创建空链表
{
linklist h;
h = (linklist)malloc(sizeof(linknode));
h->next = NULL;
return h;
}
int EmptyLinklist(linklist h) //判断表是否为空
{
return (NULL == h->next);
}
int LengthLinklist(linklist h) //测表长度
{
int len = 0;
h = h->next;
while (h != NULL)//若表指针不为空,继续遍历知道出现空的节点,说明已到表尾
{
len++;
h = h->next;
}
return len;
}
void VisitLinklist(linklist h)//遍历链表,并打印节点中的数据
{
h = h->next;
while (h != NULL)
{
printf("%d ", h->data);
h = h->next;
}
printf("\n");
}
linklist SearchLinklist(linklist h, datatype x)//查找和x相等的节点数据,返回其地址;若不存在,返回NULL
{
h = h->next;
while (h != NULL)
{
if (h->data == x) break;
h = h->next;
}
return h;
}
void InsertLinklist_tail(linklist h, datatype x) //将x插入表尾
{
linklist p;
while(h->next != NULL) h = h->next; //遍历找到表尾之后创建新节点将x插入
p = (linklist)malloc(sizeof(linknode));
p->data = x;
p->next = NULL;
h->next = p;
}
void InsertLinklist_sort(linklist h, datatype x)//将x插入表中并排序
{
linklist p;
while ((h->next != NULL) && (h->next->data < x)) h = h->next;
p = (linklist)malloc(sizeof(linknode));
p->data = x;
p->next = h->next;
h->next = p;
}
void DeleteLinklist(linklist h, datatype x)//删除链表中所有和x相等的数据节点
{
linklist p = h->next;
while (p != NULL)
{
if (p->data == x)
{
h->next = p->next;
free(p);
}
else
{
h = h->next;
}
p = h->next;
}
}
#if 1
void ClearLinklist(linklist h) //释放链表h中除了头结点之外的所有结点
{
linklist p;
while (h->next != NULL)
{
p = h->next;
h->next = p->next;
free(p);
}
}
#else
void ClearLinklist(linklist h)
{
linklist p, q;
p = h->next;
h->next = NULL;
while (p != NULL)
{
q = p;
p = p->next;
free(q);
}
}
#endif
void ReverseLinklist(linklist h)//链表h反转,即所有结点顺序颠倒
{
linklist p, q;
p = h->next;
h->next = NULL;
while (p != NULL)
{
q = p;
p = p->next;
q->next = h->next;
h->next = q;
}
}