1 #include <stdio.h>
2 #include <string.h>
3 #include <malloc.h>
4 #include <stdlib.h>
5
6 #define OVERFLOW 0
7 #define TRUE true
8 #define FALSE false
9 #define OK 1
10 #define ERROR 0
11
12 typedef int ElemType;
13 typedef bool Status;
14
15
16 typedef struct DuLNode{
17 //定义自己的数据类型
18 ElemType data;
19 struct DuLNode *prior, *next;
20 }DuLNode, *DuLinkList;
21
22 //带头节点的双向循环链表的基本操作
23 void InitList(DuLinkList *L){
24 //产生空的双向循环链表
25 *L = (DuLinkList)malloc(sizeof(DuLNode));
26 if(*L){
27 (*L)->next = (*L)->prior = *L;
28 }
29 else{
30 exit(OVERFLOW);
31 }
32 }
33
34 //销毁循环链表L
35 void DestroyList(DuLinkList *L){
36 DuLinkList q, p = (*L)->next; //p指向第一个结点
37 while(p != *L){
38 q = p->next;
39 free(p);
40 p = q;
41 }
42 free(*L);
43 *L = NULL;
44 }
45
46 //重置链表为空表
47 void ClearList(DuLinkList L){//不改变L
48 DuLinkList q, p = L->next; //p指向第一个结点
49 while(p != L){//p没到表头
50 q = p->next;
51 free(p);
52 p = q;
53 }
54 L->next = L->prior = L; //头结点的两个指针域均指向自身
55 }
56
57 //验证是否为空表
58 Status ListEmpty(DuLinkList L){
59 //初始条件:线性表L已存在
60 if(L->next == L && L->prior == L){
61 return TRUE;
62 }
63 else{
64 return FALSE;
65 }
66 }
67
68 //计算表内元素个数
69 int ListLength(DuLinkList L){
70 //初始条件:L已存在
71 int i = 0;
72 DuLinkList p = L->next; //p指向第一个结点
73 while(p != L){ //p没到表头
74 i++;
75 p = p->next;
76 }
77 return i;
78 }
79
80 //赋值
81 Status GetElem(DuLinkList L, int i, ElemType *e){
82 //当第i个元素存在时,其赋值给e并返回OK,否则返回ERROR
83 int j = 1; //j为计数器
84 DuLinkList p = L->next; //p指向第一个结点
85 while(p != L && p->next){
86 j++;
87 }
88 if(p == L || j < i){//第i个元素不存在
89 return ERROR;
90 }
91 *e = p->data; //取第i个元素
92 return OK;
93 }
94
95 Status compare(ElemType e1, ElemType e2){
96 if(e1 == e2){
97 return TRUE;
98 }
99 else{
100 return FALSE;
101 }
102 }
103
104 //查找元素
105 int LocateElem(DuLinkList L, ElemType e, Status(*cmppare)(ElemType, ElemType)){
106 //初始条件:L已存在, compare是数据元素判定函数
107 //操作结果:返回L中第一个与e满足关系compare()的数据元素位序
108 //若这样的数据元素不存在,则返回值为0
109 int i = 0;
110 DuLinkList p = L->next; //p指向第一个元素
111 while(p != L){
112 i++;
113 if(compare(p->data, e)){//找到这样的数据元素
114 return i;
115 }
116 p = p->next;
117 }
118 return 0;
119 }
120
121
122 //查找元素前驱
123 Status PriorElem(DuLinkList L, ElemType cur_e, ElemType *pre_e){
124 //操作结果:若cur_e是L的数据元素,且不是第一个,则用pre_e返回它的前驱
125 //否则操作失败,pre_e无定义
126 DuLinkList p = L->next->next; //p指向第二个元素
127 while(p != L){ //p没到表头
128 if(p->data == cur_e){
129 *pre_e = p->prior->data;
130 return TRUE;
131 }
132 p = p->next;
133 }
134 return FALSE;
135 }
136
137 //查找后继元素
138 Status NextElem(DuLinkList L, ElemType cur_e, ElemType *next_e){
139 //操作结果:若cur_e是L的数据元素,且不是最后一个,则用next_e返回她的后继
140 //否则操作失败,next_e无定义
141 DuLinkList p = L->next->next; //p指向第二个元素
142 while(p != L){
143 if(p->prior->data == cur_e){
144 *next_e = p->data;
145 return TRUE;
146 }
147 p = p->next;
148 }
149 return FALSE;
150 }
151
152 //查找元素地址
153 DuLinkList GetElemP(DuLinkList L, int i){//另加
154 //在双向链表L中返回第i个元素的地址,i为0,则返回头结点的地址,若第i个元素不存在,则返回NULL
155 int j;
156 DuLinkList p = L; //p指向头结点
157 if(i < 0 || ListLength(L)) {//i值不合法
158 return NULL;
159 }
160 for(j = 1; j <= i; j++){
161 p = p->next;
162 }
163 return p;
164 }
165
166 //元素的插入
167 Status lisInsert(DuLinkList L, int i, ElemType e){
168 //在带头结点的双向循环链表L中的第i个位置之前插入元素e,i的合法值为1<= i <= 表长 + 1
169 //改进算法2.18,否则无法在第表长+1个节点之前插入元素
170 DuLinkList p, s;
171 if(i < 1 || i > ListLength(L) + 1){ //i值不合法
172 return ERROR;
173 }
174 p = GetElemP(L, i - 1);//在L中确定第i个元素的前驱的位置指针p
175 if(!p){ //p = NULL,即第i个元素的前驱不存在(设头结点为第1个元素的前驱)
176 return ERROR;
177 }
178 s = (DuLinkList)malloc(sizeof(DuLNode));
179 if(!s){
180 return OVERFLOW;
181 }
182 s->data = e;
183 s->prior = p; //在第i-1个元素之后插入
184 s->next = p->next;
185 p->next->prior = s;
186 p->next = s;
187 return OK;
188 }
189
190 //元素的删除
191 Status ListDelete(DuLinkList L, int i, ElemType *e){
192 //删除带头结点的双向循环链表L的第i个元素,i的合法值为1<= i <= 表长
193 DuLinkList p;
194 if(i < 1){//i值不合法
195 return ERROR;
196 }
197 p = GetElemP(L, i);//在L中确定第i个元素的位置指针p
198 if(!p){//p=NULL,即第i个元素不存在
199 return ERROR;
200 }
201 *e = p->data;
202 p->prior->next = p->next;
203 p->next->prior = p->prior;
204 free(p);
205 return OK;
206 }
207
208 void *visit(ElemType e){
209 //TODO
210 }
211 //正序查找
212 void ListTraverse(DuLinkList L, void(*vist)(ElemType)){
213 //由双链循环线性表L的头结点出发,正序对每个元素调用函数visit()
214 DuLinkList p = L->next;//p指向头结点
215 while(p != L){
216 visit(p->data);
217 p = p->next;
218 }
219 printf(" ");
220 }
221
222 //逆序查找
223 void ListTraverseBack(DuLinkList L, void(*visit)(ElemType)){
224 //由双链循环线性表L的头结点出发,逆序对每个元素调用函数visit(),另加
225 DuLinkList p = L->prior;//p指向头结点
226 while(p != L){
227 visit(p->data);
228 p = p->prior;
229 }
230 printf(" ");
231 }
232
233 int main(){
234 return 0;
235 }
2 #include <string.h>
3 #include <malloc.h>
4 #include <stdlib.h>
5
6 #define OVERFLOW 0
7 #define TRUE true
8 #define FALSE false
9 #define OK 1
10 #define ERROR 0
11
12 typedef int ElemType;
13 typedef bool Status;
14
15
16 typedef struct DuLNode{
17 //定义自己的数据类型
18 ElemType data;
19 struct DuLNode *prior, *next;
20 }DuLNode, *DuLinkList;
21
22 //带头节点的双向循环链表的基本操作
23 void InitList(DuLinkList *L){
24 //产生空的双向循环链表
25 *L = (DuLinkList)malloc(sizeof(DuLNode));
26 if(*L){
27 (*L)->next = (*L)->prior = *L;
28 }
29 else{
30 exit(OVERFLOW);
31 }
32 }
33
34 //销毁循环链表L
35 void DestroyList(DuLinkList *L){
36 DuLinkList q, p = (*L)->next; //p指向第一个结点
37 while(p != *L){
38 q = p->next;
39 free(p);
40 p = q;
41 }
42 free(*L);
43 *L = NULL;
44 }
45
46 //重置链表为空表
47 void ClearList(DuLinkList L){//不改变L
48 DuLinkList q, p = L->next; //p指向第一个结点
49 while(p != L){//p没到表头
50 q = p->next;
51 free(p);
52 p = q;
53 }
54 L->next = L->prior = L; //头结点的两个指针域均指向自身
55 }
56
57 //验证是否为空表
58 Status ListEmpty(DuLinkList L){
59 //初始条件:线性表L已存在
60 if(L->next == L && L->prior == L){
61 return TRUE;
62 }
63 else{
64 return FALSE;
65 }
66 }
67
68 //计算表内元素个数
69 int ListLength(DuLinkList L){
70 //初始条件:L已存在
71 int i = 0;
72 DuLinkList p = L->next; //p指向第一个结点
73 while(p != L){ //p没到表头
74 i++;
75 p = p->next;
76 }
77 return i;
78 }
79
80 //赋值
81 Status GetElem(DuLinkList L, int i, ElemType *e){
82 //当第i个元素存在时,其赋值给e并返回OK,否则返回ERROR
83 int j = 1; //j为计数器
84 DuLinkList p = L->next; //p指向第一个结点
85 while(p != L && p->next){
86 j++;
87 }
88 if(p == L || j < i){//第i个元素不存在
89 return ERROR;
90 }
91 *e = p->data; //取第i个元素
92 return OK;
93 }
94
95 Status compare(ElemType e1, ElemType e2){
96 if(e1 == e2){
97 return TRUE;
98 }
99 else{
100 return FALSE;
101 }
102 }
103
104 //查找元素
105 int LocateElem(DuLinkList L, ElemType e, Status(*cmppare)(ElemType, ElemType)){
106 //初始条件:L已存在, compare是数据元素判定函数
107 //操作结果:返回L中第一个与e满足关系compare()的数据元素位序
108 //若这样的数据元素不存在,则返回值为0
109 int i = 0;
110 DuLinkList p = L->next; //p指向第一个元素
111 while(p != L){
112 i++;
113 if(compare(p->data, e)){//找到这样的数据元素
114 return i;
115 }
116 p = p->next;
117 }
118 return 0;
119 }
120
121
122 //查找元素前驱
123 Status PriorElem(DuLinkList L, ElemType cur_e, ElemType *pre_e){
124 //操作结果:若cur_e是L的数据元素,且不是第一个,则用pre_e返回它的前驱
125 //否则操作失败,pre_e无定义
126 DuLinkList p = L->next->next; //p指向第二个元素
127 while(p != L){ //p没到表头
128 if(p->data == cur_e){
129 *pre_e = p->prior->data;
130 return TRUE;
131 }
132 p = p->next;
133 }
134 return FALSE;
135 }
136
137 //查找后继元素
138 Status NextElem(DuLinkList L, ElemType cur_e, ElemType *next_e){
139 //操作结果:若cur_e是L的数据元素,且不是最后一个,则用next_e返回她的后继
140 //否则操作失败,next_e无定义
141 DuLinkList p = L->next->next; //p指向第二个元素
142 while(p != L){
143 if(p->prior->data == cur_e){
144 *next_e = p->data;
145 return TRUE;
146 }
147 p = p->next;
148 }
149 return FALSE;
150 }
151
152 //查找元素地址
153 DuLinkList GetElemP(DuLinkList L, int i){//另加
154 //在双向链表L中返回第i个元素的地址,i为0,则返回头结点的地址,若第i个元素不存在,则返回NULL
155 int j;
156 DuLinkList p = L; //p指向头结点
157 if(i < 0 || ListLength(L)) {//i值不合法
158 return NULL;
159 }
160 for(j = 1; j <= i; j++){
161 p = p->next;
162 }
163 return p;
164 }
165
166 //元素的插入
167 Status lisInsert(DuLinkList L, int i, ElemType e){
168 //在带头结点的双向循环链表L中的第i个位置之前插入元素e,i的合法值为1<= i <= 表长 + 1
169 //改进算法2.18,否则无法在第表长+1个节点之前插入元素
170 DuLinkList p, s;
171 if(i < 1 || i > ListLength(L) + 1){ //i值不合法
172 return ERROR;
173 }
174 p = GetElemP(L, i - 1);//在L中确定第i个元素的前驱的位置指针p
175 if(!p){ //p = NULL,即第i个元素的前驱不存在(设头结点为第1个元素的前驱)
176 return ERROR;
177 }
178 s = (DuLinkList)malloc(sizeof(DuLNode));
179 if(!s){
180 return OVERFLOW;
181 }
182 s->data = e;
183 s->prior = p; //在第i-1个元素之后插入
184 s->next = p->next;
185 p->next->prior = s;
186 p->next = s;
187 return OK;
188 }
189
190 //元素的删除
191 Status ListDelete(DuLinkList L, int i, ElemType *e){
192 //删除带头结点的双向循环链表L的第i个元素,i的合法值为1<= i <= 表长
193 DuLinkList p;
194 if(i < 1){//i值不合法
195 return ERROR;
196 }
197 p = GetElemP(L, i);//在L中确定第i个元素的位置指针p
198 if(!p){//p=NULL,即第i个元素不存在
199 return ERROR;
200 }
201 *e = p->data;
202 p->prior->next = p->next;
203 p->next->prior = p->prior;
204 free(p);
205 return OK;
206 }
207
208 void *visit(ElemType e){
209 //TODO
210 }
211 //正序查找
212 void ListTraverse(DuLinkList L, void(*vist)(ElemType)){
213 //由双链循环线性表L的头结点出发,正序对每个元素调用函数visit()
214 DuLinkList p = L->next;//p指向头结点
215 while(p != L){
216 visit(p->data);
217 p = p->next;
218 }
219 printf(" ");
220 }
221
222 //逆序查找
223 void ListTraverseBack(DuLinkList L, void(*visit)(ElemType)){
224 //由双链循环线性表L的头结点出发,逆序对每个元素调用函数visit(),另加
225 DuLinkList p = L->prior;//p指向头结点
226 while(p != L){
227 visit(p->data);
228 p = p->prior;
229 }
230 printf(" ");
231 }
232
233 int main(){
234 return 0;
235 }