本次实现的是带有头结点的双向循环链表。此文参考了百度文库中的内容。
其基本操作有14个。
typedef struct DuLNode { ElemType data; DuLNode *prior,*next; }DuLNode,*DuLinkList; //函数声明 void InitList(DuLinkList *L);//初始化链表 void ClearList(DuLinkList L);//清空表 void DestroyList(DuLinkList &L);//销毁双向链表 int ListEmpty(DuLinkList L);//判断表是否为空 int ListLength(DuLinkList L);//判断表的长度 int GetElem(DuLinkList L,int i,ElemType *e);//返回第i个元素的值 //返回L中第1个与e满足关系compare()的数据元素的位序 int LocateElem(DuLinkList L,ElemType e,int(*compare)(ElemType,ElemType)); int PriorElem(DuLinkList L,ElemType cur_e,ElemType *pre_e);//前驱判断 int NextElem(DuLinkList L,ElemType cur_e,ElemType *next_e);//后继判断 DuLinkList GetElemP(DuLinkList L,int i);//返回第i个元素的地址 int ListInsert(DuLinkList L,int i,ElemType e);//在表的第i个位置之前插入元素e int ListDelete(DuLinkList L,ElemType *e);//删除表中第i个元素 void ListTraverse(DuLinkList L,void(*visit)(ElemType));//正序对每个元素调用函数visit() void ListTraverseBack(DuLinkList L,void(*visit)(ElemType));//逆序对每个元素调用函数visit() /* 产生空间的双向循环链表 */ void InitList(DuLinkList *L) { *L=(DuLinkList)malloc(sizeof(DuLNode)); if(NULL != (*L)) (*L)->next = (*L)->prior = (*L); else exit(0); } /* 清空链表 */ void ClearList(DuLinkList L) { DuLinkList p = L->next;//p指向第一个结点 while(p != L) { p = p->next; free(p->prior); } L->next = L->prior = L;//头结点的两个指针域指向其身 } /* 销毁双向循环链表L */ void DestroyList(DuLinkList *L) { DuLinkList q,p = (*L)->next; /* p指向第一个结点 */ while(p != (*L)) /* p没到表头 */ { q = p->next; free(p); p = q; } free((*L)); (*L) = NULL; } /* 初始条件:线性表L已存在。操作结果:若L为空表,则返回TRUE,否则返回FALSE */ int ListEmpty(DuLinkList L) { if(L->next == L && L->prior == L) return true; else return false; } /* 返回表的长度 */ int ListLength(DuLinkList L) { int len = 0; DuLinkList p = L->next;//p指向第一个结点 while(p != L) { len++; p = p->next; } return len; } /* 当第i个元素存在时,其值赋给e并返回OK,否则返回ERROR */ int GetElem(DuLinkList L,int i,ElemType *e) { int j =1 ; DuLinkList p = L->next;//p指向第一个结点 while(p != L && j < i)//顺指针向后查找,直到p指向第i个元素 { j++; p = p->next; } if(p == L || j > i) return -1; *e = p->data; return 0; } /* 初始条件:L已存在,compare()是数据元素判定函数 */ /* 操作结果:返回L中第1个与e满足关系compare()的数据元素的位序。 */ /* 若这样的数据元素不存在,则返回值为0 */ int LocateElem(DuLinkList L,ElemType e,int(*compare)(ElemType,ElemType)) { int i = 0; DuLinkList p = L->next; while(p != L)//p未指向头结点 { i++; if(compare(p->data,e))//找到这样的元素 return i; p = p->next; } return 0; } /* 操作结果:若cur_e是L的数据元素,且不是第一个,则用pre_e返回它的前驱, */ /* 否则操作失败,pre_e无定义 */ int PriorElem(DuLinkList L,ElemType cur_e,ElemType *pre_e) { DuLinkList p = L->next->next;//p指向第2个元素 while(p != L) { if(p->data == cur_e)//p指向值为cur_e的结点 { *pre_e = p->prior->data;//将p的前驱结点的值赋给 return 0; } p = p->next; } return -1; } /* 操作结果:若cur_e是L的数据元素,且不是最后一个,则用next_e返回它的后继, */ /* 否则操作失败,next_e无定义 */ int NextElem(DuLinkList L,ElemType cur_e,ElemType *next_e) { DuLinkList p = L->next->next;//p指向第二个元素 while(p != L) { if(p->prior->data == cur_e)//p所指结点的前驱指向cur_e { *next_e = p->data;//将p所指结点的值赋给next_e return 0; } p = p->next; } return -1; } /* 在双向链表L中返回第i个元素的地址。i为0,返回头结点的地址。若第i个元素不存在,返回NULL*/ DuLinkList GetElemP(DuLinkList L,int i) { int j; DuLinkList p = L; //p指向头结点 if(i < 0 || i > ListLength(L)) return NULL; for(j = 1;j <= i;j++) //p指向第i个结点 p = p->next; //p指向下一个结点 return p; } /* 在带头结点的双链循环线性表L中第i个位置之前插入元素e,i的合法值为1≤i≤表长+1 */ int ListInsert(DuLinkList L,int i,ElemType e) { DuLinkList p,s; if(i < 1 || i > ListLength(L)+1) return -1; p = GetElemP(L,i-1);//在L中确定第i个结点前驱的位置指针p if(!p) return -1; s = (DuLinkList)malloc(sizeof(DuLNode));//生成新结点 if(!s) return -1; s->data = e; //将e赋给新的结点 s->prior = p; //新结点的前驱为第i-1个结点 s->next = p->next; //新结点的后继为第i个结点 p->next->prior = s;//第i个结点的前驱指向新结点 p->next = s; //第i-1个结点的后继指向新结点 return 0; } /* 删除带头结点的双链循环线性表L的第i个元素,i的合法值为1≤i≤表长 */ int ListDelete(DuLinkList L, int i, ElemType *e) { DuLinkList p; if(i < 1) return -1; p = GetElemP(L,i);//在L中确定第i个元素的位置指针 if(!p) return -1; *e = p->data;//把第i个结点的元素的值赋给e p->prior->next = p->next;//第原i-1个结点的后继指向原第i+1个结点 p->next->prior = p->prior;//第原i+1个结点的前驱指向原第i-1个结点 free(p); return OK; } /* 由双向循环链表的表头出发,正序对每个数据元素调用函数visit() */ void ListTraverse(DuLinkList L,void(*visit)(ElemType)) { DuLinkList p = L->next;//p指向首元结点 while(p != L) { visit(p->data);//对p所指结点调用函数visit() p = p->next; } printf("\n"); } /* 由双向循环链表的表头出发,逆序对每个元素调用函数visit() */ void ListTraverseBack(DuLinkList L,void(*visit)(ElemType)) { DuLinkList p = L->prior;//p指向尾结点 while(p != L) { visit(p->data); p=p->prior; } printf("\n"); }