广义表 的另一种 存储结构是 扩展线性链表存储表示,这种 存储结构的 根 节点 必 存在,并且 根节点的 表尾 为空,将 根节点的 表尾 放 在 表头 的 表尾 指针上。
这样 从 表头 一直 就可以 遍历 所有 同级 节点。
具体j结构 如下:
例如 下面的 广义表 ,用 扩展线性链表 表示为:
而 头尾 存储表示,是 把 表头 和 表尾 都放在 根节点 的 指针上。其存储结构如下:
所以 其 实现 代码略有 不同,要 小心 处理
下面 上代码:
// GList2.cpp : 定义控制台应用程序的入口点。 // // GList.cpp : 定义控制台应用程序的入口点。 //广义表的扩展线性链表存储方式 #include "stdafx.h" #include <cstdlib> #include <cstring> #define MAX_SIZE 500 typedef char ATomType; enum ElemTag{ Tag_Atom, Tag_List, }; enum E_State{ E_State_Error = 0, E_State_Ok = 1, }; typedef struct GLNode{ ElemTag tag; union { ATomType data;//原子数据 GLNode * hLink;//表头 }; GLNode * nextLink;//指向后继节点》。 }*GList; void initGList(GList * list){ *list = NULL; } //最简版的 subString,没有判断边界条件,效率最高 void subString(char * s,char * sub,int startIndex,int len){ for (int i = 1; i < startIndex; i++,s++); for (int i = 0; i < len; i++) sub[i] = s[i]; sub[len] = '\0'; } //分离 出 表头 字符串. void strSep(char * sub,char * hSub){ int i =0; int k = 0;//左括号不匹配的个数 int len = strlen(sub); for (;i < len; i++){ if (sub[i] == '(') k++; if (sub[i] == ')') k--; if (sub[i] == ',' && k == 0)break; } if (i < len){ subString(sub,hSub,1,i); subString(sub,sub,i+2,len-i-1); } else{//表头即为 sub subString(sub,hSub,1,len); sub[0] = '\0'; } //printf("%s\t%s\n",hSub,sub); } void createGList(GList * list,char * string){ GList p = *list = (GList)malloc(sizeof(GLNode)); if (strcmp(string,"()") == 0){ p->tag = Tag_List; p->hLink = p->nextLink = NULL; } else { int len = strlen(string); if (len == 1){//原子结构 p->tag = Tag_Atom; p->nextLink = NULL; p->data = string[0]; } else{ p->nextLink = NULL; p->tag = Tag_List; char sub[MAX_SIZE]; subString(string,sub,2,len-2);//去掉 最外层 () char hSub[MAX_SIZE]; strSep(sub,hSub); createGList(&p->hLink,hSub); p = p->hLink; //创建头结点后继 while (sub[0] != '\0'){ strSep(sub,hSub); createGList(&p->nextLink,hSub); p = p->nextLink; } } } } //后序释放.. void destoryGList(GList * list){ if (*list != NULL){ if ((*list)->tag != Tag_Atom){ destoryGList(&(*list)->hLink); } destoryGList(&(*list)->nextLink); free(*list); *list = NULL; } } void copyList(GList * to,GList from){ if (from != NULL){ GList p = *to = (GList)malloc(sizeof(GLNode)); p->tag = from->tag; if (from->tag == Tag_Atom){ p->data = from->data; } else{ copyList(&(*to)->hLink,from->hLink); } copyList(&(*to)->nextLink,from->nextLink); } else{//少加了下面的两句 *to = NULL; } } //求广义表的长度 //list = (a1,a2,a3....an), 长度 为n int listLen(GList list){ int len = 0; list = list->hLink; while (list != NULL){ len ++; list = list->nextLink; } return len; } //求广义表的深度 ,广义表括弧的重数.. //list = (a1,a2,a3....an), 深度为:max(listDepth(a1),listDepth(a2),listDepth(a3)...)+1 int listDepth(GList list){ if (list == NULL || list->tag == Tag_List && list->hLink == NULL){ return 1; } else if(list->tag == Tag_Atom){ return 0; } else { int max = 0; GList p = list->hLink; for (;p != NULL; p=p->nextLink){ int depth = listDepth(p); if (max < depth){ max = depth; } } return max +1; } } bool isListEmpty(GList list){ return list == NULL ? true : false; } GList getHead(GList list){ return list == NULL ? NULL : list->hLink; } GList getTail(GList list){ return list == NULL ? NULL : list->hLink->nextLink; } //插入一个元素在表头 GList insertFirst(GList * list,ATomType data){ //错误 //GList newList = (GList) malloc(sizeof(GLNode)); //newList->tag = Tag_List; //newList->nextLink = NULL; GList head = (GList) malloc(sizeof(GLNode)); //newList->hLink = head; head->tag = Tag_Atom; head->data = data; GList p = (*list)->hLink; (*list)->hLink = head; head->nextLink = p;; //*list = newList; return *list; } void deleteFirst(GList * list){ GList p = (*list)->hLink->nextLink; (*list)->hLink->nextLink = NULL; destoryGList(list); *list = p; } void printGList(GList list){ if (list != NULL){ if (list->tag == Tag_Atom){//原子节点 没有头节点.. printf("%c",list->data); } else{ printGList(list->hLink); } printGList(list->nextLink); } } int _tmain(int argc, _TCHAR* argv[]) { printf("-----------------创建广义表----------------\n"); printf("请输入广义表,用() 表示表类型,用,分割表成员:"); char s[MAX_SIZE]; scanf("%s",s); GList list; createGList(&list,s); printGList(list); int len = listLen(list); int depth = listDepth(list); char * isEmpty = isListEmpty(list) ? "表为空" : "表不空"; printf("\n表长为:%d,表深:%d,%s",len,depth,isEmpty); GList head = getHead(list); GList tail = getTail(list); //printf("\n-----------------表头----------------\n"); //printGList(head); printf("\n-----------------表尾----------------\n"); printGList(tail); printf("\n-----------------在表头插入一个元素----------------\n"); insertFirst(&list,'z'); printGList(list); printf("\n-----------------删除表头----------------\n"); deleteFirst(&list); printGList(list); printf("\n-----------------拷贝广义表----------------\n"); GList copy; copyList(©,list); printGList(copy); destoryGList(&list); return 0; }
运行截图:
源码网盘地址:点击打开链接
时间: 2024-10-03 13:27:48