看数据结构写代码(52) 广义表的扩展线性链表存储表示

来源:互联网 发布:淘宝网秋天中老年帽子 编辑:程序博客网 时间:2024/06/05 15:55

广义表 的另一种 存储结构是 扩展线性链表存储表示,这种 存储结构的 根 节点 必 存在,并且 根节点的 表尾 为空,将 根节点的 表尾 放 在 表头 的 表尾 指针上。

这样 从 表头 一直 就可以 遍历 所有 同级 节点。

具体j结构 如下:


例如 下面的 广义表 ,用 扩展线性链表 表示为:


而 头尾 存储表示,是 把 表头 和 表尾 都放在 根节点 的 指针上。其存储结构如下:


所以 其 实现 代码略有 不同,要 小心 处理

下面 上代码:

// GList2.cpp : 定义控制台应用程序的入口点。//// GList.cpp : 定义控制台应用程序的入口点。//广义表的扩展线性链表存储方式#include "stdafx.h"#include <cstdlib>#include <cstring>#define MAX_SIZE 500typedef 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{//表头即为 subsubString(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), 长度 为nint 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)...)+1int 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(&copy,list);printGList(copy);destoryGList(&list);return 0;}
运行截图:

源码网盘地址:点击打开链接



0 0