1.链式结构简介
S1线性表的链式存储结构特点:
1)用任意一组地址任意的存储单元存放线性表中的数据元素。
2)节点:数据域(数据元素的信息)+指针域(指示直接后继存储位置)=节点(表示数据元素或数据元素的映像)

S2头节点以及头指针
1)有时为了操作方便,在第一个节点之前虚加以个“头节点”,以指向头节点的指针为链表的头指针。

S3线性表的顺序存储结构与链式存储结构优缺点:
1)在分配空间上:数组分配在一块连续的数据空间上,因此在分配空间时必须确定大小;链表是一块
不连续的动态空间,通过指针来连接,因此长度可变。
2)顺序存储与链式存储优缺点:
数组优点:
1.可以利用偏移地址来访问元素,效率高,为O(1)。
2.可以使用折半方法查找元素,效率高。
数组缺点:
1.空间连续,存储效率低。
2.插入和删除元素效率比较低,而且比较麻烦。
链表优点:
1.插入和删除元素不需要移动其余元素,效率高,为O(1)。
2.不要求连续空间,空间利用率高。
链表缺点:
1.不提高随机访问元素的机制。
2.查找元素和搜索元素的效率低,最快情况为O(1),平均情况为O(N)。
总结:因此对于经常插入和删除的操作,数据结构采用链表或者使用二叉搜索树。
S4线性表链表元素的插入与删除

注意:删除一个节点的时候,要把被删除掉节点的内存进行释放,以免造成内存泄漏。
C语言释放内存函数是:free()
2.参考代码
1.linklist.h<span style="font-family:Comic Sans MS;">#ifndef _LNK_LIST_H_
#define _LNK_LIST_H_
typedef int data_t;
typedef struct node_t {
data_t data;
struct node_t *next;
} linknode_t, *linklist_t;
/*
* create a empty list
* Input: void
* Output: void
* Return: new list, NULL when failed
*/
linklist_t CreateEmptyLinklist();
/*
* destroy a list
* Input: the list to be destroied.
* Output: void
* Return: void
*/
void DestroyLinklist(linklist_t list);
/*
* clear the list
* Input: the list to be cleared.
* Output: void
* Return: void
*/
void ClearLinklist(linklist_t list);
/*
* judge if the list is empty
* Input: the list to be tested.
* Output: void
* Return:
* 1: list is empty
* 0: not
* -1: error
*/
int EmptyLinklist(linklist_t list);
/*
* get length of the list
* Input: the list to be tested.
* Output: void
* Return:
* >=0: length of the list
* -1: means error
*/
int LengthLinklist(linklist_t list);
/*
* get data of element at specified position
* Input :
* list: the list to be operated.
* at: the position where to get the element at, started from zero
* Output:
* x: the value returned
* Return:
* 0: success;
* -1: error
*/
int GetLinklist(linklist_t list, int at, data_t *x);
/*
* set/update data of element at specified position
* Input :
* list: the list to be operated.
* at: the position at where to set the element, started with zero
* x: the new data value
* Output: void
* Return:
* 0: success;
* -1: error
*/
int SetLinklist(linklist_t list, int at, data_t x);
/*
* iterate through the list and print out info of each element
* Input:
* list: the list to be operated.
* Output: void
* Return: void
*/
void VisitLinklist(linklist_t list);
/*
* search the element by the data value and return the position
* Input:
* list: the list to be operated.
* x: the data value to be compared when search
* Output: void
* Return:
* >=0: the position of the element found;
* -1: not found or error
*/
int SearchLinklist(linklist_t list, data_t x);
/*
* insert element before the position
* Input:
* list: the list to be operated.
* before: the position before which to insert the new element into,
* start from zero
* x: the data value
* Output: void
* Return:
* 0 : success;
* -1: error
*/
int InsertLinklist_1(linklist_t list, int before, data_t x);
/*
* insert element after the position
* Input :
* list: the list to be operated.
* after: the position after which to insert the new element into,
* start from -1, -1 means insert to the first pos of the list
* x: the data value
* Output: void
* Return:
* 0: success;
* -1: error
*/
int InsertLinklist_2(linklist_t list, int after, data_t x);
/*
* delete the element at the position specified
* Input:
* list: the list to be operated.
* at: the position at where to delete the element, start from zero
* Output: void
* Return:
* 0: success;
* !0: not found or error
*/
int DeleteLinklist_1(linklist_t list, int at);
/*
* delete the element according to the data value
* Input :
* list: the list to be operated.
* x : the data value
* Output: void
* Return:
* >0 : success, the number of element matched and deleted;
* 0 : not found
* <0 : error
*/
int DeleteLinklist_2(linklist_t list, data_t x);
/*
* reverse the list
* Input :
* list: the list to be operated.
* Output: void
* Return: the reversed list
*/
linklist_t ReverseLinklist(linklist_t list);
#endif /* _LNK_LIST_H_ */
</span>
<span style="font-family:Comic Sans MS;">#ifndef _LNK_LIST_H_
#define _LNK_LIST_H_
typedef int data_t;
typedef struct node_t {
data_t data;
struct node_t *next;
} linknode_t, *linklist_t;
/*
* create a empty list
* Input: void
* Output: void
* Return: new list, NULL when failed
*/
linklist_t CreateEmptyLinklist();
/*
* destroy a list
* Input: the list to be destroied.
* Output: void
* Return: void
*/
void DestroyLinklist(linklist_t list);
/*
* clear the list
* Input: the list to be cleared.
* Output: void
* Return: void
*/
void ClearLinklist(linklist_t list);
/*
* judge if the list is empty
* Input: the list to be tested.
* Output: void
* Return:
* 1: list is empty
* 0: not
* -1: error
*/
int EmptyLinklist(linklist_t list);
/*
* get length of the list
* Input: the list to be tested.
* Output: void
* Return:
* >=0: length of the list
* -1: means error
*/
int LengthLinklist(linklist_t list);
/*
* get data of element at specified position
* Input :
* list: the list to be operated.
* at: the position where to get the element at, started from zero
* Output:
* x: the value returned
* Return:
* 0: success;
* -1: error
*/
int GetLinklist(linklist_t list, int at, data_t *x);
/*
* set/update data of element at specified position
* Input :
* list: the list to be operated.
* at: the position at where to set the element, started with zero
* x: the new data value
* Output: void
* Return:
* 0: success;
* -1: error
*/
int SetLinklist(linklist_t list, int at, data_t x);
/*
* iterate through the list and print out info of each element
* Input:
* list: the list to be operated.
* Output: void
* Return: void
*/
void VisitLinklist(linklist_t list);
/*
* search the element by the data value and return the position
* Input:
* list: the list to be operated.
* x: the data value to be compared when search
* Output: void
* Return:
* >=0: the position of the element found;
* -1: not found or error
*/
int SearchLinklist(linklist_t list, data_t x);
/*
* insert element before the position
* Input:
* list: the list to be operated.
* before: the position before which to insert the new element into,
* start from zero
* x: the data value
* Output: void
* Return:
* 0 : success;
* -1: error
*/
int InsertLinklist_1(linklist_t list, int before, data_t x);
/*
* insert element after the position
* Input :
* list: the list to be operated.
* after: the position after which to insert the new element into,
* start from -1, -1 means insert to the first pos of the list
* x: the data value
* Output: void
* Return:
* 0: success;
* -1: error
*/
int InsertLinklist_2(linklist_t list, int after, data_t x);
/*
* delete the element at the position specified
* Input:
* list: the list to be operated.
* at: the position at where to delete the element, start from zero
* Output: void
* Return:
* 0: success;
* !0: not found or error
*/
int DeleteLinklist_1(linklist_t list, int at);
/*
* delete the element according to the data value
* Input :
* list: the list to be operated.
* x : the data value
* Output: void
* Return:
* >0 : success, the number of element matched and deleted;
* 0 : not found
* <0 : error
*/
int DeleteLinklist_2(linklist_t list, data_t x);
/*
* reverse the list
* Input :
* list: the list to be operated.
* Output: void
* Return: the reversed list
*/
linklist_t ReverseLinklist(linklist_t list);
#endif /* _LNK_LIST_H_ */
</span>
2.linklist.c
<span style="font-family:Comic Sans MS;">#include <stdio.h>
#include <stdlib.h>
#include "linklist.h"
linklist_t CreateEmptyLinklist()
{
linklist_t list;
list = (linklist_t)malloc(sizeof(linknode_t));
if (NULL != list) {
list->next = NULL;
}
return list;
}
void DestroyLinklist(linklist_t list)
{
if (NULL != list) {
ClearLinklist(list);
free(list);
}
}
int GetLinklist(linklist_t list, int at, data_t *x)
{
linknode_t *node; /* used for iteration */
int pos; /* used for iteration and compare with */
if (!list) return -1;
/* at must >= 0 */
if (at < 0) return -1;
/* start from the first element */
node = list->next;
pos = 0;
while (NULL != node) {
if (at == pos) {
if (x) {
*x = node->data;
}
return 0;
}
/* move to the next */
node = node->next;
pos++;
}
return -1;
}
int SearchLinklist(linklist_t list, data_t x)
{
int pos;
linknode_t *node;
if (!list) return -1;
/* start from the first element */
node = list->next;
pos = 0;
while (NULL != node) {
if (x == node->data) return pos;
/* move to the next */
node = node->next;
pos++;
}
/* the list is empty */
return -1;
}
void VisitLinklist(linklist_t list)
{
linknode_t *node;
int len = 0;
if (!list) return;
printf("list = {");
/* start from the first element */
node = list->next;
while (NULL != node) {
printf("%d->", node->data);
/* move to the next */
node = node->next;
len++;
}
if (len > 0)
printf("\b\b} \b\n");
else
printf("}\n");
return;
}
int InsertLinklist_1(linklist_t list, int before, data_t x)
{
linknode_t *node; /* used for iteration */
int before_before, pos;
int found = 0;
linknode_t *node_new;
if (!list) return -1;
/* before must >= 0 */
if (before < 0) return -1;
if (0 == before) {
node = list;
found = 1;
} else {
/* move to the position before "at" */
before_before = before - 1;
/* start from the first element */
node = list->next;
pos = 0;
while (NULL != node) {
if (before_before == pos) {
found = 1; /* found the position */
break;
}
/* move to the next */
node = node->next;
pos++;
}
}
if (found) {
node_new = malloc(sizeof(linknode_t));
if (NULL == node_new) {
return -1;
}
node_new->data = x; /* assigned value */
/* insert the new node into the list */
node_new->next = node->next;
node->next = node_new;
return 0;
} else {
return -1;
}
}
int DeleteLinklist_1(linklist_t list, int at)
{
linknode_t *node, *node_next; /* used for iteration */
int before_at, pos;
int found = 0;
if (!list) return -1;
/* at must >= 0 */
if (at < 0) return -1;
if (0 == at) {
node = list;
found = 1;
} else {
/* move to the position before "at" */
before_at = at - 1;
/* start from the first element */
node = list->next;
pos = 0;
while (NULL != node) {
if (before_at == pos) {
found = 1; /* found the position */
break;
}
/* move to the next */
node = node->next;
pos++;
}
}
if (found && node && node->next) {
/* skip the node->next and free it */
node_next = node->next;
node->next = node_next->next;
free(node_next);
return 0;
} else {
return -1;
}
}
linklist_t ReverseLinklist(linklist_t list)
{
linknode_t *node, *node2;
if (!list) return NULL;
/* set node pointer to the first element of the list */
node = list->next;
/* reset list header to NULL */
list->next = NULL;
while (NULL != node) {
/* backup node to node2 */
node2 = node;
/* move node to the next */
node = node->next;
/* insert the node2 into the list and put
* it at the first position of the list
*/
node2->next = list->next;
list->next = node2;
}
return list;
}
void ClearLinklist(linklist_t list)
{
linklist_t next_node;
if (NULL == list) return;
while (NULL != list->next) {
next_node = list->next;
list->next = next_node->next;
free(next_node);
}
return;
}
int EmptyLinklist(linklist_t list)
{
if (NULL != list) {
if (NULL == list->next) {
return 1;
} else {
return 0;
}
} else {
return -1;
}
}
int LengthLinklist(linklist_t list)
{
int len = 0;
linknode_t *node;
if (!list) return -1;
node = list->next;
while (NULL != node) {
len++;
node = node->next;
}
return len;
}
int SetLinklist(linklist_t list, int at, data_t x)
{
linknode_t *node; /* used for iteration */
int pos;
int found;
if (!list) return -1;
node = list->next;
pos = -1;
found = 0;
while (NULL != node) {
pos++;
if (at == pos) {
found = 1; /* found the position */
node->data = x;
break;
}
node = node->next;
}
if (found) {
return 0;
} else {
return -1;
}
}
int InsertLinklist_2(linklist_t list, int after, data_t x)
{
linknode_t *node; /* used for iteration */
int pos;
int found = 0;
linknode_t *node_new;
if (!list) return -1;
/* after must >= 0 */
if (after < -1) return -1;
/* start from the first element */
node = list;
pos = -1;
while (NULL != node) {
if (after == pos) {
found = 1; /* found the position */
break;
}
/* move to the next */
node = node->next;
pos++;
}
if (found) {
node_new = malloc(sizeof(linknode_t));
if (NULL == node_new) {
return -1;
}
node_new->data = x; /* assigned value */
/* insert the new node into the list */
node_new->next = node->next;
node->next = node_new;
return 0;
} else {
return -1;
}
}
int DeleteLinklist_2(linklist_t list, data_t x)
{
linknode_t *node, *node_prev;
int count;
if (!list) return -1;
count = 0;
node_prev = list;
node = node_prev->next;
while (NULL != node) {
if (x == node->data) {
count++;
node_prev->next = node->next;
free(node);
} else {
node_prev = node;
}
node = node_prev->next;
}
return count;
}
#if 0
/* another method to reserve the list */
linklist_t ReverseLinklist(linklist_t list)
{
linknode_t *node_prev, *node, *node_next;
if (!list) return NULL;
node_prev = NULL;
node = list->next;
while (NULL != node) {
node_next = node->next;
/* if the next node is null, the current node
* reaches the end of original list,
* make the list head point to the current node
*/
if (NULL == node_next) {
list->next = node;
}
/* reverse the linkage between nodes */
node->next = node_prev;
/* move forward */
node_prev = node;
node = node_next;
}
return list;
}
#endif</span>
<span style="font-family:Comic Sans MS;">#include <stdio.h>
#include <stdlib.h>
#include "linklist.h"
linklist_t CreateEmptyLinklist()
{
linklist_t list;
list = (linklist_t)malloc(sizeof(linknode_t));
if (NULL != list) {
list->next = NULL;
}
return list;
}
void DestroyLinklist(linklist_t list)
{
if (NULL != list) {
ClearLinklist(list);
free(list);
}
}
int GetLinklist(linklist_t list, int at, data_t *x)
{
linknode_t *node; /* used for iteration */
int pos; /* used for iteration and compare with */
if (!list) return -1;
/* at must >= 0 */
if (at < 0) return -1;
/* start from the first element */
node = list->next;
pos = 0;
while (NULL != node) {
if (at == pos) {
if (x) {
*x = node->data;
}
return 0;
}
/* move to the next */
node = node->next;
pos++;
}
return -1;
}
int SearchLinklist(linklist_t list, data_t x)
{
int pos;
linknode_t *node;
if (!list) return -1;
/* start from the first element */
node = list->next;
pos = 0;
while (NULL != node) {
if (x == node->data) return pos;
/* move to the next */
node = node->next;
pos++;
}
/* the list is empty */
return -1;
}
void VisitLinklist(linklist_t list)
{
linknode_t *node;
int len = 0;
if (!list) return;
printf("list = {");
/* start from the first element */
node = list->next;
while (NULL != node) {
printf("%d->", node->data);
/* move to the next */
node = node->next;
len++;
}
if (len > 0)
printf("\b\b} \b\n");
else
printf("}\n");
return;
}
int InsertLinklist_1(linklist_t list, int before, data_t x)
{
linknode_t *node; /* used for iteration */
int before_before, pos;
int found = 0;
linknode_t *node_new;
if (!list) return -1;
/* before must >= 0 */
if (before < 0) return -1;
if (0 == before) {
node = list;
found = 1;
} else {
/* move to the position before "at" */
before_before = before - 1;
/* start from the first element */
node = list->next;
pos = 0;
while (NULL != node) {
if (before_before == pos) {
found = 1; /* found the position */
break;
}
/* move to the next */
node = node->next;
pos++;
}
}
if (found) {
node_new = malloc(sizeof(linknode_t));
if (NULL == node_new) {
return -1;
}
node_new->data = x; /* assigned value */
/* insert the new node into the list */
node_new->next = node->next;
node->next = node_new;
return 0;
} else {
return -1;
}
}
int DeleteLinklist_1(linklist_t list, int at)
{
linknode_t *node, *node_next; /* used for iteration */
int before_at, pos;
int found = 0;
if (!list) return -1;
/* at must >= 0 */
if (at < 0) return -1;
if (0 == at) {
node = list;
found = 1;
} else {
/* move to the position before "at" */
before_at = at - 1;
/* start from the first element */
node = list->next;
pos = 0;
while (NULL != node) {
if (before_at == pos) {
found = 1; /* found the position */
break;
}
/* move to the next */
node = node->next;
pos++;
}
}
if (found && node && node->next) {
/* skip the node->next and free it */
node_next = node->next;
node->next = node_next->next;
free(node_next);
return 0;
} else {
return -1;
}
}
linklist_t ReverseLinklist(linklist_t list)
{
linknode_t *node, *node2;
if (!list) return NULL;
/* set node pointer to the first element of the list */
node = list->next;
/* reset list header to NULL */
list->next = NULL;
while (NULL != node) {
/* backup node to node2 */
node2 = node;
/* move node to the next */
node = node->next;
/* insert the node2 into the list and put
* it at the first position of the list
*/
node2->next = list->next;
list->next = node2;
}
return list;
}
void ClearLinklist(linklist_t list)
{
linklist_t next_node;
if (NULL == list) return;
while (NULL != list->next) {
next_node = list->next;
list->next = next_node->next;
free(next_node);
}
return;
}
int EmptyLinklist(linklist_t list)
{
if (NULL != list) {
if (NULL == list->next) {
return 1;
} else {
return 0;
}
} else {
return -1;
}
}
int LengthLinklist(linklist_t list)
{
int len = 0;
linknode_t *node;
if (!list) return -1;
node = list->next;
while (NULL != node) {
len++;
node = node->next;
}
return len;
}
int SetLinklist(linklist_t list, int at, data_t x)
{
linknode_t *node; /* used for iteration */
int pos;
int found;
if (!list) return -1;
node = list->next;
pos = -1;
found = 0;
while (NULL != node) {
pos++;
if (at == pos) {
found = 1; /* found the position */
node->data = x;
break;
}
node = node->next;
}
if (found) {
return 0;
} else {
return -1;
}
}
int InsertLinklist_2(linklist_t list, int after, data_t x)
{
linknode_t *node; /* used for iteration */
int pos;
int found = 0;
linknode_t *node_new;
if (!list) return -1;
/* after must >= 0 */
if (after < -1) return -1;
/* start from the first element */
node = list;
pos = -1;
while (NULL != node) {
if (after == pos) {
found = 1; /* found the position */
break;
}
/* move to the next */
node = node->next;
pos++;
}
if (found) {
node_new = malloc(sizeof(linknode_t));
if (NULL == node_new) {
return -1;
}
node_new->data = x; /* assigned value */
/* insert the new node into the list */
node_new->next = node->next;
node->next = node_new;
return 0;
} else {
return -1;
}
}
int DeleteLinklist_2(linklist_t list, data_t x)
{
linknode_t *node, *node_prev;
int count;
if (!list) return -1;
count = 0;
node_prev = list;
node = node_prev->next;
while (NULL != node) {
if (x == node->data) {
count++;
node_prev->next = node->next;
free(node);
} else {
node_prev = node;
}
node = node_prev->next;
}
return count;
}
#if 0
/* another method to reserve the list */
linklist_t ReverseLinklist(linklist_t list)
{
linknode_t *node_prev, *node, *node_next;
if (!list) return NULL;
node_prev = NULL;
node = list->next;
while (NULL != node) {
node_next = node->next;
/* if the next node is null, the current node
* reaches the end of original list,
* make the list head point to the current node
*/
if (NULL == node_next) {
list->next = node;
}
/* reverse the linkage between nodes */
node->next = node_prev;
/* move forward */
node_prev = node;
node = node_next;
}
return list;
}
#endif</span>
3.main.c
<span style="font-family:Comic Sans MS;">#include <stdio.h>
#include <stdlib.h>
#include "linklist.h"
int main(int argc, char *argv[])
{
int i;
data_t a[10] = {2, 4, 6, 8, 10, 12, 14, 16, 18, 20};
data_t x;
linklist_t list;
list = CreateEmptyLinklist();
if (NULL == list) return -1;
printf("insert method 1: insert each elment before\n");
for (i = 0; i < 10; i++) {
if (InsertLinklist_1(list, i, a[i]) < 0)
break;
}
VisitLinklist(list);
printf("clear the list\n");
ClearLinklist(list);
VisitLinklist(list);
printf("insert method 1: insert each elment after\n");
for (i = -1; i < 9; i++) {
if (InsertLinklist_2(list, i, a[i+1]) < 0)
break;
}
VisitLinklist(list);
GetLinklist(list, 4, &x);
printf("list[4] = %d\n", x);
printf("updated list[4] to 100\n");
SetLinklist(list, 4, 100);
GetLinklist(list, 4, &x);
printf("now list[4] = %d\n", x);
printf("removed list[4]\n");
DeleteLinklist_1(list, 4);
GetLinklist(list, 4, &x);
printf("now list[4] = %d\n", x);
printf("and total number of list is %d\n", LengthLinklist(list));
VisitLinklist(list);
printf("insert \"1\" before the %dth of the list\n", 0);
InsertLinklist_1(list, 0, 1);
VisitLinklist(list);
printf("reversed the list\n");
ReverseLinklist(list);
VisitLinklist(list);
ClearLinklist(list);
printf("after clear, total number of list is %d and ", LengthLinklist(list));
VisitLinklist(list);
DestroyLinklist(list);
return 0;
}</span>