链表可以有多种形式。
它可以是单链接的或双链接的,可以是已排序的或未排序的,可以是循环的或非循环的。
下面我们实现双链接、未排序、非循环,带头节点指针的链表。示意图如下:
插入和删除时间复杂度为O(1),查找最坏时间复杂度为O(n).
代码如下:

/* * 双链接、未排序、非循环链表。带头指针 */ #include <stdio.h> #include <stdlib.h> typedef struct object { int key; struct object *next,*prev; }object_s; object_s *list_search(object_s * l, int key); void list_insert(object_s **l, object_s *intx); void list_delete(object_s **l, object_s *intx); int main(void) { object_s * l=NULL; // 初始化一个链表 object_s x; x.key=5; list_insert(&l,&x); list_delete(&l,&x); if(list_search(l,5)==NULL) { printf("the link hasn't key 5. "); exit(1); } else { printf("find the value 5 "); } return 0; } // 查找链表l中第一个关键字为key的元素,并返回指向该元素的指针。 object_s *list_search(object_s * l, int key) { object_s * pobj; pobj = l; while(pobj!=NULL && pobj->key!=key) pobj = pobj->next; return pobj; } // 给定设置好关键字key的元素intx,将intx插入链表的前端 void list_insert(object_s **l, object_s *intx) { intx->next = *l; intx->prev = NULL; if(*l != NULL) (*l)->prev=intx; *l = intx; } // 将元素intx从链表l中移除 void list_delete(object_s **l, object_s *intx) { if(intx == *l) *l = intx->next; else intx->prev->next = intx->next; if(intx->next != NULL) intx->next->prev = intx->prev; }
接下来实现双链表、非排序、循环,带哨兵的链表。哨兵是一个哑对象,其作用是简化边界条件的处理。
示意图如下所示:
插入和删除时间复杂度为O(1),查找最坏时间复杂度为O(n).
代码如下:

/* * 双链接、未排序、循环链表。 * 使用哨兵,可以忽略表头和表尾处的边界条件。 */ #include <stdio.h> #include <stdlib.h> typedef struct object { int key; struct object *next,*prev; }object_s; typedef struct list { object_s nil; }list_s; object_s *list_search(list_s *list, int key); void list_insert(list_s *list, object_s *intx); void list_delete(list_s *list, object_s *intx); int main(void) { list_s lt; object_s intx; lt.nil.key=0; lt.nil.next = &(lt.nil); lt.nil.prev = &(lt.nil); intx.key=7; list_insert(<, &intx); if(list_search(<,7)==&(lt.nil)) { printf("the link hasn't key 7. "); exit(1); } else { printf("find the value 7 "); } list_delete(<,&intx); if(list_search(<,7)==&(lt.nil)) { printf("the link hasn't key 7. "); exit(1); } else { printf("find the value 7 "); } return 0; } // 查找链表l中第一个关键字为key的元素,并返回指向该元素的指针。 object_s *list_search(list_s *list, int key) { object_s * pobj; pobj = (list->nil).next; while(pobj!=&(list->nil) && pobj->key!=key) pobj = pobj->next; return pobj; } // 给定设置好关键字key的元素intx,将intx插入链表的前端 void list_insert(list_s *list, object_s *intx) { intx->next = (list->nil).next; intx->prev = &(list->nil); (list->nil).next->prev = intx; (list->nil).next = intx; } // 将元素intx从链表l中移除 void list_delete(list_s *list, object_s *intx) { intx->prev->next = intx->next; intx->next->prev = intx->prev; }