首页 > 代码库 > 02循环单链表

02循环单链表

循环单链表定义:将单链表中终端结点的指针端由空指针改为指向头结点,就使整个单链表形成了

        一个环,这种头尾相接的单链表成为单循环链表。

技术分享

循环链表的数据结构:

1 /* c2-2.h 线性表的单链表存储结构 */
2 struct LNode
3 {
4     ElemType data;
5     struct LNode *next;
6 };
7 typedef struct LNode *LinkList; /* 另一种定义LinkList的方法 */

代码实现:

  1  
  2 
  3 /* bo2-4.c 设立尾指针的单循环链表(存储结构由c2-2.h定义)的12个基本操作 */
  4  Status InitList_CL(LinkList *L)
  5  { 
  6      /* 操作结果:构造一个空的线性表L */
  7    *L=(LinkList)malloc(sizeof(struct LNode)); /* 产生头结点,并使L指向此头结点 */
  8    if(!*L) /* 存储分配失败 */
  9      exit(OVERFLOW);
 10    (*L)->next=*L; /* 指针域指向头结点 */
 11    return OK;
 12  }
 13 
 14  Status DestroyList_CL(LinkList *L)
 15  { 
 16      /* 操作结果:销毁线性表L */
 17    LinkList q,p=(*L)->next; /* p指向头结点 */
 18    while(p!=*L) /* 没到表尾 */
 19    {
 20      q=p->next;
 21      free(p);
 22      p=q;
 23    }
 24    free(*L);
 25    *L=NULL;
 26    return OK;
 27  }
 28 
 29  Status ClearList_CL(LinkList *L) /* 改变L */
 30  {
 31      /* 初始条件:线性表L已存在。操作结果:将L重置为空表 */
 32    LinkList p,q;
 33    *L=(*L)->next; /* L指向头结点 */
 34    p=(*L)->next; /* p指向第一个结点 */
 35    while(p!=*L) /* 没到表尾 */
 36    {
 37      q=p->next;
 38      free(p);
 39      p=q;
 40    }
 41    (*L)->next=*L; /* 头结点指针域指向自身 */
 42    return OK;
 43  }
 44 
 45  Status ListEmpty_CL(LinkList L)
 46  { 
 47      /* 初始条件:线性表L已存在。操作结果:若L为空表,则返回TRUE,否则返回FALSE */
 48    if(L->next==L) /**/
 49      return TRUE;
 50    else
 51      return FALSE;
 52  }
 53 
 54  int ListLength_CL(LinkList L)
 55  {
 56      /* 初始条件:L已存在。操作结果:返回L中数据元素个数 */
 57    int i=0;
 58    LinkList p=L->next; /* p指向头结点 */
 59    while(p!=L) /* 没到表尾 */
 60    {
 61      i++;
 62      p=p->next;
 63    }
 64    return i;
 65  }
 66 
 67  Status GetElem_CL(LinkList L,int i,ElemType *e)
 68  { 
 69      /* 当第i个元素存在时,其值赋给e并返回OK,否则返回ERROR */
 70    int j=1; /* 初始化,j为计数器 */
 71    LinkList p=L->next->next; /* p指向第一个结点 */
 72    if(i<=0||i>ListLength_CL(L)) /* 第i个元素不存在 */
 73      return ERROR;
 74    while(j<i)
 75    { 
 76        /* 顺指针向后查找,直到p指向第i个元素 */
 77      p=p->next;
 78      j++;
 79    }
 80    *e=p->data; /* 取第i个元素 */
 81    return OK;
 82  }
 83 
 84  int LocateElem_CL(LinkList L,ElemType e,Status(*compare)(ElemType,ElemType))
 85  {
 86      /* 初始条件:线性表L已存在,compare()是数据元素判定函数 */
 87    /* 操作结果:返回L中第1个与e满足关系compare()的数据元素的位序。 */
 88    /*           若这样的数据元素不存在,则返回值为0 */
 89    int i=0;
 90    LinkList p=L->next->next; /* p指向第一个结点 */
 91    while(p!=L->next)
 92    {
 93      i++;
 94      if(compare(p->data,e)) /* 满足关系 */
 95        return i;
 96      p=p->next;
 97    }
 98    return 0;
 99  }
100 
101  Status PriorElem_CL(LinkList L,ElemType cur_e,ElemType *pre_e)
102  { 
103      /* 初始条件:线性表L已存在 */
104    /* 操作结果:若cur_e是L的数据元素,且不是第一个,则用pre_e返回它的前驱, */
105    /*           否则操作失败,pre_e无定义 */
106    LinkList q,p=L->next->next; /* p指向第一个结点 */
107    q=p->next;
108    while(q!=L->next) /* p没到表尾 */
109    {
110      if(q->data=http://www.mamicode.com/=cur_e)
111      {
112        *pre_e=p->data;
113        return TRUE;
114      }
115      p=q;
116      q=q->next;
117    }
118    return FALSE;
119  }
120 
121  Status NextElem_CL(LinkList L,ElemType cur_e,ElemType *next_e)
122  { 
123      /* 初始条件:线性表L已存在 */
124    /* 操作结果:若cur_e是L的数据元素,且不是最后一个,则用next_e返回它的后继, */
125    /*           否则操作失败,next_e无定义 */
126    LinkList p=L->next->next; /* p指向第一个结点 */
127    while(p!=L) /* p没到表尾 */
128    {
129      if(p->data=http://www.mamicode.com/=cur_e)
130      {
131        *next_e=p->next->data;
132        return TRUE;
133      }
134      p=p->next;
135    }
136    return FALSE;
137  }
138 
139  Status ListInsert_CL(LinkList *L,int i,ElemType e) /* 改变L */
140  { 
141      /* 在L的第i个位置之前插入元素e */
142    LinkList p=(*L)->next,s; /* p指向头结点 */
143    int j=0;
144    if(i<=0||i>ListLength_CL(*L)+1) /* 无法在第i个元素之前插入 */
145      return ERROR;
146    while(j<i-1) /* 寻找第i-1个结点 */
147    {
148      p=p->next;
149      j++;
150    }
151    s=(LinkList)malloc(sizeof(struct LNode)); /* 生成新结点 */
152    s->data=http://www.mamicode.com/e; /* 插入L中 */
153    s->next=p->next;
154    p->next=s;
155    if(p==*L) /* 改变尾结点 */
156      *L=s;
157    return OK;
158  }
159 
160  Status ListDelete_CL(LinkList *L,int i,ElemType *e) /* 改变L */
161  {
162      /* 删除L的第i个元素,并由e返回其值 */
163    LinkList p=(*L)->next,q; /* p指向头结点 */
164    int j=0;
165    if(i<=0||i>ListLength_CL(*L)) /* 第i个元素不存在 */
166      return ERROR;
167    while(j<i-1) /* 寻找第i-1个结点 */
168    {
169      p=p->next;
170      j++;
171    }
172    q=p->next; /* q指向待删除结点 */
173    p->next=q->next;
174    *e=q->data;
175    if(*L==q) /* 删除的是表尾元素 */
176      *L=p;
177    free(q); /* 释放待删除结点 */
178    return OK;
179  }
180 
181  Status ListTraverse_CL(LinkList L,void(*vi)(ElemType))
182  {
183      /* 初始条件:L已存在。操作结果:依次对L的每个数据元素调用函数vi()。一旦vi()失败,则操作失败 */
184    LinkList p=L->next->next;
185    while(p!=L->next)
186    {
187      vi(p->data);
188      p=p->next;
189    }
190    printf("\n");
191    return OK;
192  }

 

02循环单链表