线性表实现——双向循环链表

Posted 沙加的孩子

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了线性表实现——双向循环链表相关的知识,希望对你有一定的参考价值。

  1 /*双向循环链表*/
  2 
  3 #include <stdio.h>
  4 #include <stdlib.h>
  5 #include <time.h>
  6 
  7 #define OK 1
  8 #define ERROR 0
  9 typedef int Status;
 10 typedef int ElemType;
 11 
 12 typedef struct DCNode
 13 {
 14     ElemType data;
 15     struct DCNode* next;
 16     struct DCNode* front;
 17 }DCNode;
 18 
 19 typedef struct DCNode* DCLinkList;
 20 
 21 Status InitList(DCLinkList* L)  //初始化操作,建立一个空的线性表.想把头指针里面的值改掉,所以传个头指针的地址
 22 {
 23     *L = (DCLinkList)malloc(sizeof(DCNode));
 24     if (!(*L))
 25         return ERROR;
 26     (*L)->next = *L;
 27     (*L)->front = *L;
 28     return OK;
 29 }
 30 Status ListEmpty(DCLinkList L)  //若线性表为空,返回true,否则返回false
 31 {
 32     if (L->next == L)
 33         return OK;
 34     return ERROR;
 35 }
 36 Status ClearList(DCLinkList* L) //清空线性表
 37 {
 38     DCLinkList p = (*L)->next;
 39     DCLinkList q;
 40     while (p != *L)
 41     {
 42         q = p;
 43         p = p->next;
 44         free(q);
 45     }
 46     (*L)->next = *L;
 47     (*L)->front = *L;
 48     return OK;
 49 }
 50 Status GetElem(DCLinkList L, int  i, ElemType *e)  //查找线性表中的第i个位置的元素值,并赋值给e
 51 {
 52     int j = 0;
 53     DCLinkList p = L->next;
 54     while ((p!=L) &&( j < i))
 55     {
 56         p = p->next;
 57         j++;
 58     }
 59     if ((p == L) || (j > i))
 60         return ERROR;
 61     *e = p->data;
 62     return OK;
 63 }
 64 Status LocateElem(DCLinkList L, ElemType e) //查找线性表L中与给定值e相等的元素,如果查找成功,则返回第一个相同的元素在L中的下标;否则,返回0表示失败
 65 {
 66     int i = 1;
 67     DCLinkList p = L->next;
 68     while (p != L && p->data != e)
 69     {
 70         p = p->next;
 71         i++;
 72     }
 73     if (p==L)
 74         return ERROR;
 75     return i;
 76 }
 77 Status ListInsert(DCLinkList* L, int i, ElemType e)  //在线性表L的第i个位置插入元素e
 78 {
 79     DCLinkList p, q;
 80     p = *L;
 81     int j = 1;
 82     p = (*L)->next;
 83     if ((*L)->next == *L)
 84     {
 85         if (i == 1)
 86         {
 87             goto ADD;
 88         }
 89     }
 90     while ((p!= *L) && j<i)    //尾部插入时,p指向最后一个值,而j=i-1
 91     {
 92         p = p->next;
 93         j++;
 94     }
 95     if ((p==*L) || j > i)
 96         return ERROR;
 97 ADD:
 98     q = (DCLinkList)malloc(sizeof(DCNode));
 99     q->data = e;
100     q->next = p->next;
101     if (p->next)
102         q->next->front = q;
103     p->next = q;
104     q->front = p;
105 
106     return ERROR;
107 }
108 Status ListDelete(DCLinkList*L, int i, ElemType* e) //删除线性表L中第i个位置元素,并用e返回其值
109 {
110     DCLinkList p, q;
111     p = *L;
112     int j = 1;
113     //while (p && j<i)
114     while ((p->next!=*L) && j<i)
115     {
116         p = p->next;
117         j++;
118     }
119     //if (!p || j > i)
120     if ((p->next == *L) || j > i)
121         return ERROR;
122     q = p->next;
123     *e = q->data;
124     p->next = q->next;
125     q->next->front = p;
126     free(q);
127     return OK;
128 }
129 Status CreateListHead(DCLinkList *L, int n)
130 {
131     DCLinkList p;
132     int i;
133     (*L) = (DCLinkList)malloc(sizeof(DCNode));
134     (*L)->next = *L;
135     (*L)->front = *L;
136     for (i = 0; i < n; i++)
137     {
138         p = (DCLinkList)malloc(sizeof(DCNode));
139         p->data = i;
140         p->next = (*L)->next;
141         p->next->front = p;
142         p->front = *L;
143         (*L)->next = p;
144     }
145     return OK;
146 }
147 Status CreateListTail(DCLinkList *L, int n)
148 {
149     DCLinkList p;
150     int i;
151     (*L) = (DCLinkList)malloc(sizeof(DCNode));
152     //(*L)->next = NULL;
153     DCLinkList q = (*L);
154     for (i = 0; i < n; i++)
155     {
156         p = (DCLinkList)malloc(sizeof(DCNode));
157         p->data = i + 10;
158         q->next = p;
159         p->front = q;
160         q = p;
161     }
162     q->next = *L;
163     (*L)->front = q;
164     return OK;
165 }
166 Status visit(ElemType n)
167 {
168     printf("-> %d  ", n);
169     return OK;
170 }
171 Status ListTraverse(DCLinkList L)
172 {
173     DCLinkList p = L->next;
174     while (p != L)
175     {
176         visit(p->data);
177         p = p->next;
178     }
179     return OK;
180 }
181 
182 int ListLength(DCLinkList L)  //返回线性表L的长度
183 {
184     int i = 0;
185     DCLinkList p = L->next;
186     while (p != L)
187     {
188         i++;
189         p = p->next;
190     }
191     return i;
192 }
193 
194 int main()
195 {
196     DCLinkList L;
197     Status i, j;
198     char opp = -1;
199     ElemType e;
200     int pos = 1;
201     int k = 0;
202 
203     i = InitList(&L);
204     printf("链表L初始化完毕,ListLength(L)=%d\n\n", ListLength(L));
205 
206     printf("\n1.遍历操作 \n2.插入操作  \n3.删除操作 \n4.获取结点数据\n5.查找某个数是否在链表中 \n6.头插法创建链表 \n7.尾插法创建链表 \n8.置空链表 \n0.退出 \n请选择你的操作:\n");
207 
208     while (opp != 0) {
209         scanf_s("%c", &opp);
210         switch (opp) {
211         case 1:
212             ListTraverse(L);
213             printf("\n");
214             break;
215 
216         case 2:
217             srand((unsigned)time(NULL));
218             for (j = 1; j <= 10; j++)
219             {
220                 i = ListInsert(&L, 1, rand() % 100);
221             }
222             printf("在L的表头依次插入10个随机数后:");
223             ListTraverse(L);
224             printf("\n");
225             printf("链表L创建完毕,ListLength(L)=%d\n\n", ListLength(L));
226             break;
227         case 3:
228             printf("要删除第几个元素?");
229             scanf_s("%d", &pos);
230             ListDelete(&L, pos, &e);
231             printf("删除第%d个元素成功,现在链表为:\n", pos);
232             ListTraverse(L);
233             printf("\n");
234             break;
235 
236         case 4:
237             printf("你需要获取第几个元素?");
238             scanf_s("%d", &pos);
239             GetElem(L, pos, &e);
240             printf("第%d个元素的值为:%d\n", pos, e);
241             printf("\n");
242             break;
243         case 5:
244             printf("输入你需要查找的数:");
245             scanf_s("%d", &pos);
246             k = LocateElem(L, pos);
247             if (k)
248                 printf("第%d个元素的值为%d\n", k, pos);
249             else
250                 printf("没有值为%d的元素\n", pos);
251             printf("\n");
252             break;
253         case 6:
254             CreateListHead(&L, 10);
255             printf("整体创建L的元素(头插法):\n");
256             ListTraverse(L);
257             printf("\n");
258             break;
259 
260         case 7:
261             CreateListTail(&L, 10);
262             printf("整体创建L的元素(尾插法):\n");
263             ListTraverse(L);
264             printf("\n");
265             break;
266 
267         case 8:
268             i = ClearList(&L);
269             printf("\n清空L后:ListLength(L)=%d\n", ListLength(L));
270             ListTraverse(L);
271             printf("\n");
272             break;
273 
274         case 0:
275             exit(0);
276         }
277     }
278 }

 

以上是关于线性表实现——双向循环链表的主要内容,如果未能解决你的问题,请参考以下文章

线性表-双向循环链表

数据结构线性表之双向带头循环链表

《链表》之带头双向循环链表

初阶数据结构——线性表——链表——带头双向循环链表

带头双向循环链表 代码实现 review

线性表——顺序表和链表