1,什么叫单向循环链表。单向循环链表是指在单链表的基础上,表的最后一个元素指向链表头结点,不再是为空。 2,由图可知,单向循环链表的判断条件不再是表为空了,而变成了是否到表头。 3,链表的结点表示 1 struct LNode 2 { 3 int data; 4 struct LNode * next; 5 }; 6 typedef struct LNode * linklist
1,什么叫单向循环链表。单向循环链表是指在单链表的基础上,表的最后一个元素指向链表头结点,不再是为空。
2,由图可知,单向循环链表的判断条件不再是表为空了,而变成了是否到表头。
3,链表的结点表示
1 struct LNode
2 {
3 int data;
4 struct LNode * next;
5 };
6 typedef struct LNode * linklist
4,单向循环链表的操作集合,仍是defs.h里的操作集合,这里就不给出了。
5,单循环链表的初始化操作。示意图
实现:
1 #include"defs.h"
2
3 void InitList(linklist *L) //改变尾指针
4 {
5 *L = (linklist)malloc(sizeof(struct LNode)); //分配头结点
6 if (*L == NULL) //分配失败
7 exit(0);
8 (*L)->next = *L; //指针域指向它本身
9 }
6,清空操作最終图和初始化的结果是一样的。
1 #include"defs.h"
2
3 void ClearList(linklist *L) //改变尾指针
4 {
5 linklist p, q;
6 *L = (*L)->next; //先令尾指针指向头结点,不然释放最后一个结点时尾指针,无法指向头结点
7 p = (*L)->next; //p指向第一个结点
8
9 while (p != *L) //p未到表头时
10 {
11 q = p->next;
12 free(p);
13 p = q;
14 }
15 *L->next = *L; //头结点指针域指向其本身
16 }
7,DestroyList操作。撤销操作是在清空操作基础上,释放了头结点。
1 #include"defs.h"
2
3 void DestroyList(linklist *L)
4 {
5 ClearList(&L);
6 free(*L); //释放头结点
7 *L = NULL;
8 }
DestroyList.c
8,ListEmpty操作。
1 #include"defs.h"
2
3 int ListEmpty(linklist L)
4 {
5 if (L->next == L) //指针域指向它本身,肯定就是空了,该结点即为头结点
6 return 0;
7 else
8 return 1; //非空为1
9 }
ListEmpty.c
9,ListLength操作
1 #include"defs.h"
2
3 int ListLength(linklist L)
4 {
5 linklist p = L->next->next; //p指向第一个结点
6 int j = 0;
7
8 while (p != L->next) //p未到表头时
9 {
10 ++j;
11 p = p->next;
12 }
13 return j;
14 }
ListLength.c
10,GetElem操作
1 #include"defs.h"
2
3 void GetElem(linklist L, int i, int *e)
4 {
5 linklist p = L->next ; //p指向头结点
6 int j = 0;
7 if (i<1 || i>ListLength(L)) //位置不合理
8 exit(0);
9
10 while (j < i) //位置合理,找到第i个结点
11 {
12 ++j;
13 p = p->next;
14 }
15 *e = p->data;
16 }
GetElem.c
11,LocateElem操作
1 #include"defs.h"
2
3 int LocateElem(linklist L, int e)
4 {
5 linklist p = L->next->next; //p指向链表第一个元素
6 int j = 0;
7
8 while (p != L->next) //p未到表头时
9 {
10 ++j;
11 if (p->data == e)
12 return j;
13 p = p->next;
14 }
15 return -1; //未找到,返回-1
16 }
LocateElem.c
12,PriorElem操作实现
1 #include"defs.h"
2
3 int PriorElem(linklist L, int cur_e, int *pri_e)
4 {
5 linklist p = L->next->next; //p指向链表第一个元素
6 linklist q;
7
8 while (p != L->next)
9 {
10 q = p->next; //q指向p的后继
11 if (q != L->next && q->data == cur_e)
12 {
13 *pri_e = p->data;
14 return 0;
15 }
16 p = q;
17 }
18 return 0;
19 }
PriorElem.c
13,NextElem操作实现
1 #include"defs.h"
2
3 int NextElem(linklist L, int cur_e, int *Nex_e) //最后一个元素无后继
4 {
5 linklist p = L->next->next; //p指向第一个结点
6 linklist q;
7
8 while (p != L->next)
9 {
10 q = p->next;
11 if (q != L->next && p->data == cur_e)
12 {
13 *Nex_e = q->data;
14 return 0;
15 }
16 p = q;
17 }
18 return 0;
19 }
NextElem.c
14,ListInsert操作实现
1 #include"defs.h"
2
3 int ListInsert(Linklist *L, int i, int e) //在表尾插入改变尾指针
4 {
5 linklist p = (*L)->next; //p指向表头
6 linklist q, s;
7 int j = 0;
8
9 if (i<1 || i>ListLength(L)+1) //插入位置不合理
10 exit(0);
11
12 while (j < i-1) //位置合理,找到第i-1个结点
13 {
14 ++j;
15 p = p->next;
16 }
17 q = p->next; //q指向第i个结点
18 s = (linklist)malloc(sizeof(struct LNode));
19 s->data = e;
20 s->next = q;
21 q->next = s;
22 if (p == *L)
23 *L = s;
24 }
15,ListDelete操作实现
1 #include"defs.h"
2
3 int ListDelete(linklist *L, int i, int *e)
4 {
5 linklist p = (*L)->next;
6 linklist q;
7 int j = 0;
8 if (i<1 || i>ListLength(L))
9 exit(0);
10
11 while (j<i-1) //找到第i-1个结点
12 {
13 ++j;
14 p = p->next;
15 }
16 q = p->next; //q指向第i个结点
17 *e = q->data;
18 p->next = q->next;
19 if (q == *L) //删除的是表尾元素,表尾指针发生改变
20 *L = p;
21 free(q);
22 return 0;
23 }
16,TravelList操作实现
1 #include"defs.h"
2
3 void TravelList(linklist L)
4 {
5 linklist p = L->next->next; //p指向第一个结点
6 int j = 0;
7
8 while (p != L->next) //p未到表头
9 {
10 ++j;
11 printf("第%d个元素为:%d\n", j, p->data);
12 p = p->next;
13 }
14 }
TravelList.c