Data Structure --- C language for storing and expressing generalized table head and tail linked lists
// The head and end of the generalized table are stored in the chain table. // Yang Xin # include
# Include
# Include
# Include
# Define MAXSTRLEN 40) typedef char SString [MAXSTRLEN + 1]; typedef char AtomType; // define the atomic type as struct typedef enum {ATOM, LIST // ATOM = 0: atomic LIST = 1: Sub-Table} ElemTag; typedef struct GLNode {ElemTag tag; // public part, used to differentiate the union between an atomic node and a table node. The union part {AtomType atom; // atom is the value field of an atomic node, atomType is defined by the user. struct {struct GLNode * hp, * tp;} ptr; // ptr is the pointer field of the table node, prt. hp and ptr. tp points to the header and end of the table} a;} * GList, GLNode; // initialized generalized table Lint InitGList (GList * L) {* L = NULL; return 1;} // destroy the generalized table Lvoid DestroyGList (GList * L) {GList q1, q2; if (* L) {if (* L)-> tag = ATOM) {free (* L); * L = NULL;} else {q1 = (* L)->. ptr. hp; q2 = (* L)->. ptr. tp; free (* L); * L = NULL; DestroyGList (& q1); DestroyGList (& q2 ); // recursively Delete the header and End Node} // use the storage structure of the head and end linked list. The generalized table T is obtained by copying the generalized table L. Int CopyGList (GList * T, GList L) {if (! L) * T = NULL; else {* T = (GList) malloc (sizeof (GLNode); if (! * T) exit (0); (* T)-> tag = L-> tag; if (L-> tag = ATOM) (* T)->. atom = L->. atom; // copy a single atom else // is a table node. Copy the header and the end of the table {CopyGList (& (* T)->. ptr. hp), L->. ptr. hp); CopyGList (& (* T)->. ptr. tp), L->. ptr. tp) ;}} return 1 ;}// return the length of the generalized table, that is, the number of elements int GListLength (GList L) {int len = 0; if (! L) return 0; if (L-> tag = ATOM) return 1; while (L) {L = L->. ptr. tp; len ++;} return len;} // uses the storage structure of the head-and-tail linked list to obtain the depth of L in the generalized table. Int GListDepth (GList L) {int max, dep; GList pp; if (! L) return 1; // The depth of the empty table is 1if (L-> tag = ATOM) return 0; // The Atomic depth is 0for (max = 0, pp = L; pp; pp = pp->. ptr. tp) {// recursively calculate pp->. ptr. depth dep = GListDepth (pp->. ptr. hp); if (dep> max) max = dep;} return max + 1; // The depth of a non-empty table is the maximum value of the depth of each element plus 1} // determine whether the generalized table is empty int GListEmpty (GList L) {if (! L) return 1; elsereturn 0;} // obtain the GList GetHead (GList L) {GList h, p; if (! L) {printf ("empty table with no header! \ N "); exit (0);} p = L->. ptr. tp; L->. ptr. tp = NULL; CopyGList (& h, L); L->. ptr. tp = p; return h;} // obtain the GList GetTail (GList L) {GList t; if (! L) {printf ("no end of the empty table! \ N "); exit (0);} CopyGList (& t, L->. ptr. tp); return t;} // insert element e as the first element of generalized table L (header or subtable) int InsertFirst_GL (GList * L, GList e) {GList p = (GList) malloc (sizeof (GLNode); if (! P) exit (0); p-> tag = LIST; p->. ptr. hp = e; p->. ptr. tp = * L; * L = p; return 1;} // Delete the first element of generalized table L and return its value int DeleteFirst_GL (GList * L, GList * e) with e) {GList p; * e = (* L)->. ptr. hp; p = * L; * L = (* L)->. ptr. tp; free (p); return 1;} // uses a recursive algorithm to traverse the generalized table L void Traverse_GL (GList L, void (* v) (AtomType) {if (L) if (L-> tag = ATOM) v (L->. atom); else {Traverse_GL (L->. ptr. hp, v); Traverse_GL (L->. ptr. tp, v) ;}}// generate a string whose value is equal to chars Tint StrAssign (SString T, char * chars) {int I; if (strlen (chars)> MAXSTRLEN) return 0; else {T [0] = strlen (chars); for (I = 1; I <= T [0]; I ++) T [I] = * (chars + I-1); return 1 ;}// the Tint StrCopy (SString T, SString S) {int I; for (I = 0; I <= S [0]; I ++) T [I] = S [I]; return 1 ;}// if S is an empty string, 1 is returned; otherwise, 0 int StrEmpty (SString S) {if (S [0] = 0) return 1; elsereturn 0 ;}// if S> T, the return value is greater than 0. If S is T, the return value is 0. If S is
S [0] | len <0 | len> S [0]-pos + 1) return 0; for (I = 1; I <= len; I ++) sub [I] = S [pos + I-1]; Sub [0] = len; return 1;} // split non-empty string str into two parts: hsub is the first ', 'substring before, str is the substring void sever (SString str, SString hstr) {int n, I, k; SString ch, c1, c2, c3; n = StrLength (str); StrAssign (c1, ","); StrAssign (c2, "("); StrAssign (c3, ")"); SubString (ch, str, 1, 1); for (I = 1, k = 0; I <= n & StrCompare (ch, c1) | k! = 0; ++ I) {SubString (ch, str, I, 1); if (! StrCompare (ch, c2) ++ k; else if (! StrCompare (ch, c3) -- k;} if (I <= n) {SubString (hstr, str, 1, I-2); SubString (str, str, I, n-I + 1);} else {StrCopy (hstr, str); ClearString (str) ;}// generalized table L. Set emp = "()" int CreateGList (GList * L, SString S) {SString sub, hsub, emp; GList p, q; StrAssign (emp ,"()"); if (! StrCompare (S, emp) * L = NULL; // create an empty table else {* L = (GList) malloc (sizeof (GLNode); if (! * L) // The table creation node exit (0); if (StrLength (S) = 1) // S is a single ATOM {(* L)-> tag = ATOM; (* L)->. atom = S [1]; // create a single atomic generalized table} else {(* L)-> tag = LIST; p = * L; SubString (sub, S, 2, strLength (S)-2); // remove the outer parenthesis do {// re-create n sub tables sever (sub, hsub ); // separate the hsub CreateGList (& p->. ptr. hp, hsub); q = p; if (! StrEmpty (sub) // the end of the table is not empty {p = (GLNode *) malloc (sizeof (GLNode); if (! P) exit (0); p-> tag = LIST; q-> a. ptr. tp = p;} while (! StrEmpty (sub); q->. ptr. tp = NULL ;}} return 1 ;}// print the atomic void visit (AtomType e) {printf ("% c", e) ;} int main () {// the generalized table is expressed as an empty table: (), single atom: a, Table :( a, (B), c, (d, (e ))) char p [80] = {"(a, (B), c, (d, (e)"}; SString t; GList L, m; initGList (& L); InitGList (& m); printf ("Empty generalized table L depth = % d \ nL is empty? % D (1: 0: No) \ n ", GListDepth (L), GListEmpty (L); StrAssign (t, p); CreateGList (& L, t); // create a generalized table printf ("\ n generalized table L length = % d \ n", GListLength (L )); printf ("is the depth of generalized table L % d \ nL empty? % D (1: 0: No) \ n ", GListDepth (L), GListEmpty (L); printf (" traverse generalized table L: \ n "); traverse_GL (L, visit); printf ("\ n copying generalized table m = L \ n"); CopyGList (& m, L ); printf ("length of generalized table m = % d \ n", GListLength (m); printf ("depth of generalized table m = % d \ n ", GListDepth (m); printf ("traversing generalized table m: \ n"); Traverse_GL (m, visit); DestroyGList (& m); m = GetHead (L ); printf ("\ n \ nm is the L header, traversing the generalized table m: \ n"); Traverse_GL (m, visit); DestroyGList (& m ); m = GetTail (L); printf ("\ n \ nm is the end of the L table, traversing the generalized table m: \ n"); Traverse_GL (m, visit ); insertFirst_GL (& m, L); printf ("\ n Insert the header where L is m, traverse the generalized table m: \ n"); Traverse_GL (m, visit ); printf ("\ n Delete the m header and traverse the generalized table m: \ n"); DestroyGList (& L); DeleteFirst_GL (& m, & L ); traverse_GL (m, visit); printf ("\ n"); DestroyGList (& m); return 0 ;}