广义表——头尾链表存储表示的定义与相关操作

Posted hongdoudou

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了广义表——头尾链表存储表示的定义与相关操作相关的知识,希望对你有一定的参考价值。

  1 /****************************************************
  2  *                                                    *
  3  * 文件夹: ▲05 数组和广义表5 GeneralizedList-H&T *
  4  *                                                     *
  5  * 文件名: GeneralizedList-H-T.h                    *
  6  *                                                     *
  7  * 内  容: 广义表(头尾链表存储表示)相关操作列表   *
  8  *                                                     *
  9  ****************************************************/
 10 
 11 #ifndef GENERALIZEDLIST_H_T_H
 12 #define GENERALIZEDLIST_H_T_H
 13 
 14 #include <stdio.h>
 15 #include <stdlib.h>                                            //提供malloc、realloc、free、exit原型
 16 #include "../../01 绪论/Status.h"                            //**▲01 绪论**//
 17 #include "../../04 串/01 SequenceString/SequenceString.c"    //**▲04 串**//
 18 
 19 /* 广义表(头尾链表存储表示)类型定义 */
 20 typedef enum{ Head, Tail }Mark;
 21 typedef enum{ Atom, List }ElemTag;            //Atom==0:原子结点,List==1:表结点
 22 typedef char AtomType;                        //原子类型
 23 typedef struct GLNode
 24 {
 25     union{ int mark; };                        //匿名联合,仅在第8章广义表遍历算法中使用 
 26     
 27     ElemTag tag;                            //公共部分,用于区分原子结点和表结点 
 28     union                                    //原子结点和表结点的联合部分 
 29     {
 30         AtomType atom;                        //atom是原子结点的值域,AtomType由用户定义 
 31         struct
 32         {
 33             struct GLNode *hp;                //指向表头
 34             struct GLNode *tp;                //指向表尾 
 35         }ptr;                                //表结点的指针域 
 36     }Union;
 37 }GLNode;
 38 typedef GLNode* GList;                        //广义表类型 
 39 
 40 /* 广义表(头尾链表存储)函数列表 */
 41 /* ★每一层去掉括号考察★ */
 42 void InitGList_GL_H_T(GList *L);
 43 /*━━━━━━━━━━━━━━━━━━━┓
 44 ┃(01)初始化广义链表(创建空的广义表)。┃
 45 ┗━━━━━━━━━━━━━━━━━━━*/
 46 
 47 void sever_GL_H_T_1(SString hstr, SString str);
 48 /*━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
 49 ┃(02-1)算法5.8:将非空串str分割成两部分:hsub为第一个‘,‘之前的子串,str为之后的子串。┃
 50 ┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━*/
 51 
 52 void CreateGList_GL_H_T_1(GList *L, SString S);
 53 /*━━━━━━━━━━━━━━━┓
 54 ┃(03-1)算法5.7:由S创建广义表。┃
 55 ┗━━━━━━━━━━━━━━━*/
 56 
 57 void sever_GL_H_T_2(SString hstr, SString str);
 58 /*━━━━━━━━━━━━━━━━━━━━━━━━━━┓
 59 ┃(02-2)将非空串str分割成两部分:hsub做表头,str做表尾。┃
 60 ┗━━━━━━━━━━━━━━━━━━━━━━━━━━*/
 61 
 62 void CreateGList_GL_H_T_2(GList *L, SString S);
 63 /*━━━━━━━━━━━┓
 64 ┃(03-2)由S创建广义表。 ┃
 65 ┗━━━━━━━━━━━*/
 66 
 67 void ClearGList_GL_H_T(GList *L);
 68 /*━━━━━━━━━━━━━━┓
 69 ┃(04)清空广义表(无法销毁)。┃
 70 ┗━━━━━━━━━━━━━━*/
 71 
 72 void CopyGList_GL_H_T(GList *T, GList L);
 73 /*━━━━━━━━━━━━━┓
 74 ┃(05)算法5.6:复制广义表。 ┃
 75 ┗━━━━━━━━━━━━━*/
 76 
 77 int GListLength_GL_H_T(GList L);
 78 /*━━━━━━━━━┓
 79 ┃(06)求广义表长度。┃
 80 ┗━━━━━━━━━*/
 81 
 82 int GListDepth_GL_H_T(GList L);
 83 /*━━━━━━━━━━━━━━┓
 84 ┃(07)算法5.5:求广义表深度。 ┃
 85 ┗━━━━━━━━━━━━━━*/
 86 
 87 Status GListEmpty_GL_H_T(GList L);
 88 /*━━━━━━━━━━━━┓
 89 ┃(08)判断广义表是否为空。┃
 90 ┗━━━━━━━━━━━━*/
 91 
 92 GList GetHead_GL_H_T(GList L);
 93 /*━━━━━━━┓
 94 ┃(09)获取表头。┃
 95 ┗━━━━━━━*/
 96 
 97 GList GetTail_GL_H_T(GList L);
 98 /*━━━━━━━┓
 99 ┃(10)获取表尾。┃
100 ┗━━━━━━━*/
101 
102 void InsertFirst_GL_H_T(GList *L, GList e);
103 /*━━━━━━━━━━━━━━━┓
104 ┃(11)插入e为广义表第一个元素。 ┃
105 ┗━━━━━━━━━━━━━━━*/
106 
107 void DeleteFirst_GL_H_T(GList *L, GList *e);
108 /*━━━━━━━━━━━━━━━┓
109 ┃(12)删除广义表表头并用e返回。 ┃
110 ┗━━━━━━━━━━━━━━━*/
111 
112 void Traverse_GL_H_T(GList L, void(Visit)(AtomType));
113 /*━━━━━━━━┓
114 ┃(13)遍历广义表。┃
115 ┗━━━━━━━━*/
116 
117 void Output_GL_H_T(GList L, Mark mark);
118 /*━━━━━━━━━━━━━━━━━━┓
119 ┃(14)带括号输出广义表L,mark为标记。 ┃
120 ┗━━━━━━━━━━━━━━━━━━*/
121 
122 #endif
  1 /****************************************************
  2  *                                                    *
  3  * 文件夹: ▲05 数组和广义表5 GeneralizedList-H&T *
  4  *                                                     *
  5  * 文件名: GeneralizedList-H-T.c                    *
  6  *                                                     *
  7  * 算  法: 5.5、5.6、5.7、5.8                       * 
  8  *                                                     *
  9  ****************************************************/
 10 
 11 #ifndef GENERALIZEDLIST_H_T_C
 12 #define GENERALIZEDLIST_H_T_C
 13 
 14 #include "GeneralizedList-H-T.h"                         //**▲05 数组和广义表**//
 15 
 16 void InitGList_GL_H_T(GList *L)
 17 {
 18     *L = NULL;                                            //初始化了一个空表,长度为0,深度为1 
 19 }
 20 
 21 /*════╗
 22 ║ 算法5.8║ 
 23 ╚════*/
 24 /* 假设广义表各字符间无空格,且输入正确 */
 25 void sever_GL_H_T_1(SString hstr, SString str)            //str最外层已无括号 
 26 {
 27     int i, k, n;
 28     SString ch;
 29     
 30     n = StrLength_Sq(str);
 31     
 32     i = k = 0;
 33     do
 34     {
 35         ++i;
 36         SubString_Sq(ch, str, i, 1);
 37         if(ch[1]==()
 38             ++k;
 39         if(ch[1]==))
 40             --k;
 41     }while(i<n && (ch[1]!=, || k!=0));
 42     
 43     if(i<n)
 44     {
 45         SubString_Sq(hstr, str, 1, i-1);
 46         SubString_Sq(str, str, i+1, n-i);
 47     }
 48     else
 49     {
 50         StrCopy_Sq(hstr, str);
 51         ClearString_Sq(str);
 52     }
 53 }
 54 
 55 /*════╗
 56 ║ 算法5.7║ 
 57 ╚════*/
 58 void CreateGList_GL_H_T_1(GList *L, SString S)
 59 {
 60     SString emp, hsub, sub;
 61     GList p, q;
 62     
 63     StrAssign_Sq(emp, "()");    
 64     
 65     if(!StrCompare_Sq(S, emp))                            //S代表空表
 66         *L = NULL;                                        //创建空表
 67     else
 68     {
 69         *L = (GList)malloc(sizeof(GLNode));
 70         if(!*L)
 71             exit(OVERFLOW);
 72         
 73         if(StrLength_Sq(S)==1)                            //创建单原子广义表
 74         {
 75             (*L)->tag = Atom;
 76             (*L)->Union.atom = S[1];
 77             
 78             (*L)->mark = 0;                                //GarbageCollection.c 
 79         }
 80         else
 81         {
 82             (*L)->tag = List;
 83 
 84             (*L)->mark = 0;                                //GarbageCollection.c
 85             
 86             p = *L;
 87             
 88             SubString_Sq(sub, S, 2, StrLength_Sq(S)-2);    //去掉最外层括号 
 89                                             
 90             do                                            //重复建n个子表 
 91             {    
 92                 sever_GL_H_T_1(hsub, sub);                //分离出表头串hsub    
 93                 CreateGList_GL_H_T_1(&(p->Union.ptr.hp), hsub);
 94                 q = p;
 95                 if(!StrEmpty_Sq(sub))                    //表尾不为空,处理表尾 
 96                 {                                    
 97                     p = (GList)malloc(sizeof(GLNode));
 98                     if(!p)
 99                         exit(OVERFLOW);
100                         
101                     p->tag = List;
102 
103                     p->mark = 0;                        //GarbageCollection.c 
104 
105                     q->Union.ptr.tp = p;
106                 }            
107             }while(!StrEmpty_Sq(sub));
108             q->Union.ptr.tp = NULL;
109         }
110     }
111 }
112 
113 /* 另一种创建广义表的算法,与上述算法略有不同 */
114 /* 假设广义表各字符间无空格,且输入正确 */
115 void sever_GL_H_T_2(SString hstr, SString str)            //将str分解为表头元素和表尾元素两部分 
116 {
117     int i = 1;
118     int k = 0;
119     int n;
120     SString tmp;
121     
122     SubString_Sq(tmp, str, 2, StrLength_Sq(str)-2);
123     
124     n = StrLength_Sq(tmp);
125     
126     while(i<n && (tmp[i]!=, || k!=0))
127     {
128         if(tmp[i]==()
129             k++;
130         if(tmp[i]==))
131             k--;
132         i++;
133     }
134     
135     if(i<n)
136         SubString_Sq(hstr, tmp, 1, i-1);
137     else
138         StrCopy_Sq(hstr, tmp);
139     
140     StrDelete_Sq(str, 2, i);        
141 }
142 
143 void CreateGList_GL_H_T_2(GList *L, SString S)
144 {
145     SString hsub, sub, emp;
146     GList p, q;
147     
148     StrAssign_Sq(emp, "()");
149     
150     if(!StrCompare_Sq(S, emp))
151         *L = NULL;    
152     else
153     {    
154         *L = (GList)malloc(sizeof(GLNode));
155         
156         if(StrLength_Sq(S)==1)
157         {
158             (*L)->tag = Atom;
159             (*L)->Union.atom = S[1];
160         }
161         else
162         {            
163             (*L)->tag = List;
164             p = *L;
165             
166             StrCopy_Sq(sub, S);
167             
168             do
169             {                
170                 sever_GL_H_T_2(hsub, sub);
171                 CreateGList_GL_H_T_2(&(p->Union.ptr.hp), hsub);
172                 
173                 if(StrCompare_Sq(sub, emp))
174                 {
175                     q = p;
176                     p = (GList)malloc(sizeof(GLNode));
177                     p->tag = List;
178                     q->Union.ptr.tp = p;
179                 }
180             }while(StrCompare_Sq(sub, emp));
181             p->Union.ptr.tp = NULL;
182         }    
183     }
184 }
185 
186 void ClearGList_GL_H_T(GList *L)
187 {
188     GList p, q;
189     
190     if(*L)
191     {
192         if((*L)->tag==Atom)
193          {
194             free(*L);                                     //删除原子结点
195             *L = NULL;              
196          }
197         else                                            //删除表结点
198         {
199             p = (*L)->Union.ptr.hp;
200             q = (*L)->Union.ptr.tp;
201             free(*L);
202             *L = NULL;
203             ClearGList_GL_H_T(&p);
204             ClearGList_GL_H_T(&q);
205         }
206     }    
207 }
208 
209 /*════╗
210 ║ 算法5.6║ 
211 ╚════*/
212 void CopyGList_GL_H_T(GList *T, GList L)
213 {
214     if(!L)
215         *T = NULL;
216     else
217     {
218         *T = (GList)malloc(sizeof(GLNode));                //建表结点            
219         if(!*T)
220             exit(OVERFLOW);
221         
222         (*T)->tag = L->tag;
223         
224         if(L->tag==Atom)                                //复制单原子
225             (*T)->Union.atom = L->Union.atom; 
226         else                                            //复制表头和表尾 
227         {
228             CopyGList_GL_H_T(&((*T)->Union.ptr.hp), L->Union.ptr.hp);
229             CopyGList_GL_H_T(&((*T)->Union.ptr.tp), L->Union.ptr.tp);
230         }
231     }    
232 }
233 
234 int GListLength_GL_H_T(GList L)
235 {
236     int count;
237     
238     for(count=0; L; count++,L=L->Union.ptr.tp)
239         ;
240     
241     return count; 
242 }
243 
244 /*════╗
245 ║ 算法5.5║ 
246 ╚════*/
247 int GListDepth_GL_H_T(GList L)
248 {
249     int max, deep;
250     GList p;
251     
252     if(!L)                                                //空表深度为1 
253         return 1;
254 
255     if(L->tag==Atom)                                    //原子深度为0 
256         return 0;
257     
258     for(max=0,p=L; p; p=p->Union.ptr.tp)
259     {
260         deep = GListDepth_GL_H_T(p->Union.ptr.hp);
261         if(deep>max)
262             max = deep;
263     }
264         
265     return max + 1;                                        //非空表的深度是各元素最大深度加一 
266 }
267 
268 Status GListEmpty_GL_H_T(GList L)
269 {
270     if(!L)
271         return TRUE;
272     else
273         return FALSE;
274 }
275 
276 GList GetHead_GL_H_T(GList L)
277 {
278     GList p;
279     
280     if(!L)
281     {
282         printf("广义表为空表,无法获取表头!
");
283         exit(ERROR);
284     }
285     
286     CopyGList_GL_H_T(&p, L->Union.ptr.hp);
287     
288     return p;
289 }
290 
291 GList GetTail_GL_H_T(GList L)
292 {
293     GList p;
294     
295     if(!L)
296     {
297         printf("广义表为空表,无法获取表尾!
");
298         exit(ERROR);
299     }
300     
301     CopyGList_GL_H_T(&p, L->Union.ptr.tp);
302     
303     return p;
304 }
305 
306 void InsertFirst_GL_H_T(GList *L, GList e)
307 {
308     GList g;
309     
310     g = (GList)malloc(sizeof(GLNode));
311     if(!g)
312         exit(OVERFLOW);
313             
314     g->tag = 1;    
315     g->Union.ptr.hp = e;
316     g->Union.ptr.tp = *L;
317     *L = g;
318 }
319 
320 void DeleteFirst_GL_H_T(GList *L, GList *e)
321 {
322     GList p;
323     
324     if(!(*L))
325     {
326         printf("广义表为空表,删除表头失败!
");
327         exit(ERROR);
328     }
329     
330     p = *L;
331     *L = (*L)->Union.ptr.tp;
332     
333     CopyGList_GL_H_T(e, p->Union.ptr.hp);
334     
335     free(p);    
336     p = NULL;
337 }
338 
339 void Traverse_GL_H_T(GList L, void(Visit)(AtomType))
340 {
341     if(L)
342     {
343         if(L->tag==Atom)
344             Visit(L->Union.atom);
345         else
346         {
347             Traverse_GL_H_T(L->Union.ptr.hp, Visit);
348             Traverse_GL_H_T(L->Union.ptr.tp, Visit);
349         }
350     }
351 }
352 
353 void Output_GL_H_T(GList L, Mark mark)
354 {
355     if(!L)                                                //L为空 
356     {
357         if(mark==Head)                                    //mark=0代表广义表指针来自表头 
358             printf("()");
359         else                                            //mark=1代表广义表指针来自表尾 
360             printf(")");
361     }
362     else                                                //L不为空时 
363     {
364         if(L->tag==Atom)                                //对于原子结点,输出原子 
365             printf("%c",L->Union.atom);
366         else                                            //对于表结点,要对表头、表尾分别讨论 
367         {
368             if(mark==Head)
369                 printf("(");
370             else
371                 printf(",");
372 
373             Output_GL_H_T(L->Union.ptr.hp, Head);
374             Output_GL_H_T(L->Union.ptr.tp, Tail);
375         }
376     }            
377 }
378 
379 #endif

 

以上是关于广义表——头尾链表存储表示的定义与相关操作的主要内容,如果未能解决你的问题,请参考以下文章

广义表的概念及存储表示

数据结构相关

5-6-广义表(扩展线性链表存储表示)-数组和广义表-第5章-《数据结构》课本源码-严蔚敏吴伟民版

第四章学习小结

数据结构22:数组和广义表

数据结构与算法学习笔记 线性表Ⅱ