以下为“带头节点的、单循环链表”的简单示例:
1. 用c语言实现的版本
#include<stdio.h> /* EOF(=^Z或F6),NULL */ #include<math.h> /* floor(),ceil(),abs() */ #include<stdlib.h> /* 申请和释放内存 */ #define TRUE 1 #define FALSE 0 #define OK 1 #define ERROR 0 typedef int Status; /* Status是函数的类型,其值是函数结果状态代码,如OK等 */ typedef int ElemType; /* 线性表的单链表存储结构 */ struct LNode { ElemType data; struct LNode *next; }; typedef struct LNode *LinkList; /* 另一种定义LinkList的方法 */ /* 构造一个空的、单向循环链表L */ Status InitList_CL(LinkList *L) { *L = (LinkList)malloc(sizeof(struct LNode)); /* 产生头结点,并使L指向此头结点 */ if (!*L) /* 存储分配失败 */ { exit(OVERFLOW); } (*L)->next = *L; /* 指针域指向头结点 */ return OK; } /* 若L为空表,则返回TRUE,否则返回FALSE */ Status ListEmpty_CL(LinkList L) { if (L->next == L) /* 表尾指针所指元素的next值 等于 自身 */ { return TRUE; } else { return FALSE; } } /* 返回L中数据元素个数 */ int ListLength_CL(LinkList L) { int i = 0; LinkList p = L->next; /* p指向头结点 */ while (p != L) /* 没到表尾 */ { ++i; p = p->next; } return i; } /* 在L的第i个位置插入元素e */ Status ListInsert_CL(LinkList *L, int i, ElemType e) /* 改变L */ { LinkList p = (*L)->next, s; /* p指向头结点 */ int j = 0; if (i<1 || (i>ListLength_CL(*L) + 1)) /* 无法在第i个位置插入 */ { return ERROR; } while (j < (i - 1)) /* 寻找第i-1个结点 */ { p = p->next; ++j; } s = (LinkList)malloc(sizeof(struct LNode)); /* 生成新结点 */ /* 在第i个位置插入L中 */ s->data = e; s->next = p->next; p->next = s; /* 改变尾结点 */ if (p == *L) { *L = s; } return OK; } /* 当第i个元素存在时,其值赋给e并返回OK,否则返回ERROR */ Status GetElem_CL(LinkList L, int i, ElemType *e) { int j = 1; /* 初始化,j为计数器 */ LinkList p = L->next->next; //由于L为带表头的、单向循环链表的表尾指针,所以p为第一个有效结点 if ((i < 1) || i > ListLength_CL(L)) /* 第i个元素不存在 */ { return ERROR; } while (j<i) { /* 顺指针向后查找,直到p指向第i个元素 */ p = p->next; ++j; } *e = p->data; /* 取第i个元素 */ return OK; } /* 在L的第i个位置删除元素 */ Status ListDelete_CL(LinkList *L, int i) { LinkList p = (*L)->next, s; /* 由于L为带表头的、单向循环链表的表尾指针,所以p指向头结点 */ int j = 0; if (i<1 || i>ListLength_CL(*L)) /* 无法删除第i个位置上的元素 */ { return ERROR; } while (j < (i - 1)) /* 寻找第i-1个结点 */ { p = p->next; ++j; } /* 删除第i个位置上的元素 */ s = p->next; p->next = s->next; /* 改变尾结点 */ if (s == *L) { *L = p; } free(s); return OK; } /* 依次对L的每个数据元素调用函数vi()。一旦vi()失败,则操作失败 */ Status ListTraverse_CL(LinkList L, void(*vi)(ElemType)) { LinkList p = L->next->next; //由于L为带表头的、单向循环链表的表尾指针,所以p为第一个有效结点 while (p != L->next) { vi(p->data); p = p->next; } return OK; } /* 若cur_e是L的数据元素,且不是第一个,则用pre_e返回它的前驱,否则操作失败,pre_e无定义 */ Status PriorElem_CL(LinkList L, ElemType cur_e, ElemType *pre_e) { LinkList q, p = L->next->next; //由于L为带表头的、单向循环链表的表尾指针,所以p为第一个有效结点 q = p->next; while (q != L->next) /* p没到表尾 */ { if (q->data == cur_e) { *pre_e = p->data; return TRUE; } p = q; q = q->next; } return FALSE; } /* 若cur_e是L的数据元素,且不是最后一个,则用next_e返回它的后继,否则操作失败,next_e无定义 */ Status NextElem_CL(LinkList L, ElemType cur_e, ElemType *next_e) { LinkList p = L->next->next; //由于L为带表头的、单向循环链表的表尾指针,所以p为第一个有效结点 while (p != L) /* p没到表尾 */ { if (p->data == cur_e) { *next_e = p->next->data; return TRUE; } p = p->next; } return FALSE; } /* 返回L中第1个与e满足关系compare()的数据元素的位序。若这样的数据元素不存在,则返回值为0 */ int LocateElem_CL(LinkList L, ElemType e, Status(*compare)(ElemType, ElemType)) { int i = 0; LinkList p = L->next->next; //由于L为带表头的、单向循环链表的表尾指针,所以p为第一个有效结点 while (p != L->next) { ++i; if (compare(p->data, e)) /* 满足关系 */ return i; p = p->next; } return 0; } // 比较函数 Status compare(ElemType c1, ElemType c2) { if (c1 == c2) { return TRUE; } else { return FALSE; } } void visit(ElemType c) { printf("%d ", c); } /* 销毁线性表L */ Status DestroyList_CL(LinkList *L) { LinkList q, p = (*L)->next; /* 由于L为带表头的、单向循环链表的表尾指针,p指向头结点 */ while (p != *L) /* 没到表尾 */ { q = p->next; free(p); p = q; } free(*L); *L = NULL; return OK; } /* 将L重置为空表 */ Status ClearList_CL(LinkList *L) { LinkList p, q; *L = (*L)->next; /* 由于L为带表头的、单向循环链表的表尾指针,其后继结点为头结点 */ p = (*L)->next; /* p指向第一个结点 */ while (p != *L) /* 没到表尾 */ { q = p->next; free(p); p = q; } (*L)->next = *L; /* 头结点指针域指向自身 */ return OK; } /* 合并两个单循环链表 */ void MergeList_CL(LinkList *La, LinkList Lb) { LinkList p = Lb->next; //由于Lb为带表头的、单向循环链表的表尾指针,所以p为单循环链表Lb的头节点 Lb->next = (*La)->next; //将单循环链表Lb的后继 更新为 La的头节点 (*La)->next = p->next; //将单循环链表la的后继 更新为 Lb的第一个有效节点 free(p); //释放 单循环链表Lb的头节点 *La = Lb; //将La的值 更新为 Lb的值,使两者都指向 合并后的 新链表的表尾 } void main() { LinkList L,Lb;//带头节点的、单向循环链表的表尾指针 ElemType e; int j; Status i; /* 初始化单循环链表L */ i = InitList_CL(&L); if (i == OK) { printf("初始化单循环链表成功.\n"); } else { printf("初始化单循环链表失败!\n"); return; } i = ListEmpty_CL(L); if (i == OK) { printf("单循环链表为空.\n"); } else { printf("单循环链表非空!\n"); } ListInsert_CL(&L, 1, 3); /* 在L中第1个位置插入3 */ ListInsert_CL(&L, 2, 5); /* 在L中第2个位置插入5 */ ListInsert_CL(&L, 3, 7); /* 在L中第2个位置插入5 */ /* 获取第1个位置的元素 */ i = GetElem_CL(L, 1, &e); if (i == OK) { printf("L中第%d个元素的值为%d。\n", 1, e); } else { printf("未能获取L中第%d个元素,请检查!\n", 1); return ; } j = LocateElem_CL(L, 5, compare); if (j) { printf("元素5的位置为%d\n", j); } else { printf("元素5不在单循环列表中\n"); } //返回它的前驱 i = PriorElem_CL(L, 5, &j); if (i == OK) { printf("L中元素%d的前驱为%d。\n", 5, j); } else { printf("未能获取L中元素%d的前驱(或者,它已是第一个元素,或该元素本是不存在)!\n", 5); } //返回它的后继 i = NextElem_CL(L, 5, &j); if (i == OK) { printf("L中元素%d的后继为%d。\n", 5, j); } else { printf("未能获取L中元素%d的后继(或者,它已是最后一个元素,或该元素本是不存在)!\n", 5); } /* 返回L中数据元素个数 */ j = ListLength_CL(L); printf("L中数据元素个数=%d。\n", j); printf("L中的数据元素依次为:"); ListTraverse_CL(L, visit); /* 在L的第1个位置删除元素 */ j = 3; i = ListDelete_CL(&L, j); if (i == OK) { printf("\n单循环链表成功删除第%d个元素.\n", j); } else { printf("\n单循环链表删除第%d个元素失败!\n", j); return; } /* 返回L中数据元素个数 */ j = ListLength_CL(L); printf("L中数据元素个数=%d。\n", j); printf("L中的数据元素依次为:"); ListTraverse_CL(L, visit); /* 将L重置为空表 */ i = ClearList_CL(&L); if (i == OK) { printf("\n已经重置单循环链表\n"); } /* 返回L中数据元素个数 */ j = ListLength_CL(L); printf("重置后,L中数据元素个数=%d。\n", j); /* 销毁单循环链表 */ i = DestroyList_CL(&L); if (i == OK) { printf("已经销毁单循环链表,链表尾指针已经置为%0x.\n", L); } //////////////////////////////////////////////////////// ////测试链表合并 i = InitList_CL(&L); if (i == OK) { printf("初始化单循环链表成功.\n"); } else { printf("初始化单循环链表失败!\n"); return; } ListInsert_CL(&L, 1, 3); /* 在L中第1个位置插入3 */ ListInsert_CL(&L, 2, 5); /* 在L中第2个位置插入5 */ ListInsert_CL(&L, 3, 7); /* 在L中第2个位置插入5 */ i = InitList_CL(&Lb); if (i == OK) { printf("初始化单循环链表成功.\n"); } else { printf("初始化单循环链表失败!\n"); return; } ListInsert_CL(&Lb, 1, 2); /* 在L中第1个位置插入3 */ ListInsert_CL(&Lb, 2, 4); /* 在L中第2个位置插入5 */ ListInsert_CL(&Lb, 3, 6); /* 在L中第2个位置插入5 */ MergeList_CL(&L, Lb); //合并两个单循环链表 printf("在合并后的单循环链表中,数据元素依次为:"); ListTraverse_CL(Lb, visit); printf("\n"); }运行结果如下图所示: