赞
踩
线性表的推广
(1)表的元素可以是子表,子表的元素还可以是子表
(2)列表为其他列表所享有
(3)列表可以是一个可以递归的表,即列表可以是其本身的子表
可以是单个元素,也可以是广义表,分别为广义表LS的原子和子表
习惯上,用大写字母表示广义表的名称,用小写字母表示原子。
当广义表LS非空时,称第一个元素 为LS的表头(Head),称其余元素组成的表()是LS的表尾(Tail)
(1)A = ()
(2)B = (e)
(3)C = (a,(b,c,d))
(4)D = (A,B,C)
GetHead(B) = e GetTail(B) = ()
GetHead(D) = A GetTail(D) = (B,C)
GetHead((B,C)) = B GetTail((B,C)) = (C)
()(空表)长度为0,(())(非空表)长度为1
表结点
tag = 1 | hp | tp |
原子结点
tag = 0 | atom |
- ADT GList{
- 数据对象:D={ei|i=1,2,...,n;n>=0;ei∈AtomSet或ei∈GList,
- AtomSet为某个数据对象}
- 数据关系:R1={<ei-1,ei>|ei-1,ei∈D,2<=i<=n}
- 基本操作:
- InitGList(&L);
- 操作结果:创建空的广义表.
- CreateGList(&L,S);
- 初始条件:S是广义表的书写形式串。
- 操作结果:有S创建广义表L。
- DestoryGList(&L);
- 初始条件:广义表L存在
- 操作结果:销毁广义表L。
- CopyGList(&T,L);
- 初始条件:广义表L存在
- 操作结果:由广义表L复制得到广义表T。
- GListLength(L);
- 初始条件:广义表L存在
- 操作结果:求广义表的长度,即元素个数
- GListDepth(L);
- 初始条件:广义表L的深度
- 操作结果:求广义表的深度
- GListEmpty(L);
- 初始条件:广义表存在
- 操作结果:判定广义表L是否为空
- GetHead(L);
- 初始条件:广义表L存在
- 操作结果:取广义表L的头
- GetTail(L);
- 初始条件:广义表L存在
- 操作结果:取广义表的尾
- InsertFirst_GL(&L,e);
- 初始条件:广义表L存在
- 操作结果:插入元素e作为广义表的第一元素。
- DeleteFirst_GL(&L,&e);
- 初始条件:广义表L存在
- 操作结果:删除广义表L的第一个元素,并用e返回其值
- Traverse_GL(L,visit());
- 初始条件:广义表L存在
- 操作结果:遍历广义表L,用函数visit处理每个元素
- }ADT GList;
建立广义表
基本项:
当S为空表串时,置空广义表
当S为单字符串时,建原子结点子表
归纳项:
sub为脱去最外层括弧的子串,'s1,s2,...,sn',为非空子串。对每一个Si建立一个表结点,并令其hp域的指针为由si建立的子表的头指针,除最后建立的表结点的尾指针为NULL之外,其余表结点的为指针均指向在它之后建立的表结点。
复制广义表
基本项:
InitGList(NEXLS){置空表},当LS为空表时
归纳项:
COPY(GetHead(LS)->GetHead(NEWLS)){复制表头}
COPY(GetTail(LS)->GetTail(NEWLS)){复制表尾}
求广义表的深度
基本项:
DEPTH(LS)=1 当LS为空表时
DEPTH(LS)=0 当LS为原子时
归纳项:
DEPTH(LS)=1+Max{DEPTH(
)}
- // 广义表.cpp : 定义控制台应用程序的入口点。
- //以字符串形式
-
- # include<stdio.h>
- # include<stdlib.h>
- # include<string.h>
-
- # define Status int
- # define AtomType char
- # define OK 1
- # define ERROR 0
- # define OVERFLOW -1
- # define MaxLength 60
- # include<iostream>
-
- using namespace std;
-
- typedef struct
- {
- AtomType str[MaxLength];
- Status length;
- }SString;//自定义字符串
-
- typedef enum {ATOM,LIST}ElemTag;//ATOM=0表示原子,List=1表示子表
- typedef struct GLNode
- {
- ElemTag tag;//标志tag用于区分元素是原子还是子表
- union
- {
- AtomType atom;//原子结点的值域,用户自己定义的类型
- struct {
- struct GLNode *hp, *tp;//hp指向表头,tp指向表尾
- }ptr;
- };
- }*GList,GLNode;
-
- //判断是否为空字符串
- Status StrEmpty(SString S)
- {
- if (S.length == 0)
- return OK;
- else
- return ERROR;
- }
-
- //求串长度
- Status StrLength(SString S)
- {
- return S.length;
- }
-
- //串比较
- Status StrCompare(SString S, SString T)
- {
- int i;
-
- for (i = 0; i < S.length && i < T.length; ++i)
- {
- if (S.str[i] != T.str[i])
- return S.str[i] - T.str[i];//返回第一个比较不同字符的大小
- }
-
- return S.length - T.length;//比较结束,返回两个串差值
- }
-
- //清空串
- void StrClear(SString *S)
- {
- S->length = 0;
- }
-
- //串的赋值操作
- void StrCopy(SString *T, SString S)
- {
- int i;
- for (i = 0; i < S.length; ++i)
- {
- T->str[i] = S.str[i];
- }
-
- T->length = S.length;
- }
-
- //串赋值
- void StrAssign(SString *S, char str[])
- {
- int i;
- for (i = 0; str[i] != '\0'; ++i)
- S->str[i] = str[i];
- S->length = i;
- }
-
- //截取从pos开始的长度为len的子串
- Status SubString(SString *Sub,SString S,int pos,int len)
- {
- int i;
-
- if (pos < 0 || len < 0 || pos + len - 1 > S.length)
- {
- printf("参数不合法!\n");
- return ERROR;
- }
- else
- {
- for (i = 0; i < len; ++i)
- Sub->str[i] = S.str[i + pos - 1];
- Sub->length = len;
-
- return OK;
- }
- }
-
- //将串Str分离成两个部分,HeadStr为第一个逗号之前的子串,Str为逗号后的子串
- void DistributeString(SString *Str,SString *HeadStr)
- {
- int i, len, k;
- SString ch, ch1, ch2, ch3;
- len = StrLength(*Str);
- StrAssign(&ch1, ",");
- StrAssign(&ch2, "(");
- StrAssign(&ch3, ")");
- SubString(&ch, *Str, 1, 1);//ch保存Str的第一个字符
-
- for (i = 0, k = 0; i <= len && StrCompare(ch, ch1) || k != 0; ++i)
- {//搜索str的最外层的第一个括号
- SubString(&ch, *Str, i, 1);
- if (!StrCompare(ch, ch2))
- k++;
- else if (!StrCompare(ch, ch3))
- k--;
- }
-
- if (i <= len)
- {
- SubString(HeadStr, *Str, 1, i - 2);
- SubString(Str, *Str, i, len - i + 1);
- }
- else//只包含一个子串
- {
- StrCopy(HeadStr, *Str);
- StrClear(Str);
- }
- }
-
- //创建广义表
- void CreateList(GList *L,SString S)
- {
- SString Sub, HeadSub, Empty;
- GList p, q;
- StrAssign(&Empty, "()");
-
- if (!StrCompare(S, Empty))
- *L = NULL;//如果输入是空串,则创建一个空的广义表
- else
- {
- if (!(*L = (GList)malloc(sizeof(GLNode))))
- {
- printf("内存分配失败!\n");
- exit(OVERFLOW);
- }
- if (StrLength(S) == 1)
- {//原子类型广义表
- (*L)->atom = S.str[0];
- (*L)->tag = ATOM;
- }
- else
- {
- (*L)->tag = LIST;
- p = *L;
- SubString(&Sub, S, 2, StrLength(S) - 2);//去除外层括号
- do {
- DistributeString(&Sub, &HeadSub);//将Sub分离出表头和表尾
- CreateList(&(p->ptr.hp), HeadSub);
- q = p;
- if (!StrEmpty(Sub))
- {
- if (!(p = (GLNode *)malloc(sizeof(GLNode)))) {
- printf("内存分配失败!\n");
- exit(OVERFLOW);
- }
- p->tag = LIST;
- q->ptr.tp = p;
- }
- } while (!StrEmpty(Sub));
-
- q->ptr.tp = NULL;
- }//else else
- }//else
- }
-
- //输出广义表的串表示形式
- void PrintList(GList L)
- {
- if (!L)
- {
- printf("()");
- }
- else
- {
- if (L->tag == ATOM)
- {
- printf("%c",L->atom);
- }
- else
- {
- printf("(");
- GLNode *p = L;
- while (p)
- {
- PrintList(p->ptr.hp);
- p = p->ptr.tp;
- if (p)
- printf(",");
- }//while
- printf(")");
- }//else else
- }//else
- }
-
- //获取广义表的表头节点
- Status GetHead(GList L)
- {
- if (L == NULL)
- {
- printf("广义表为空!\n");
- return ERROR;
- }
- GLNode *Head = L->ptr.hp;
- if (Head->tag == ATOM)
- {
- printf("表头:%c\n",Head->atom);
- }
- else
- {
- printf("表头:");
- PrintList(Head);
- printf("\n");
- }
-
- return OK;
- }
-
- //获取表尾节点
- Status GetTail(GList L)
- {
- if (L == NULL)
- {
- printf("空表!\n");
- return ERROR;
- }
-
- GLNode *tail = L->ptr.tp;
- printf("表尾:");
- PrintList(tail);
- printf("\n");
-
- return OK;
- }
-
- //求广义表长度
- Status GListLength(GList L)
- {
- int length = 0;
- GLNode *p = L;
- if (p == NULL)
- {
- printf("空表\n");
- return ERROR;
- }
- else
- {
- length = GListLength(p->ptr.tp);
- }
-
- return length + 1;
- }
-
- //求广义表的深度
- Status GListDepth(GList L)
- {
- int max,depth;
- GLNode *p;
- if (!L)
- return 1;
- if (L->tag == ATOM)
- return 0;
- for (max = 0, p = L; p; p = p->ptr.tp)
- {
- depth = GListDepth(p->ptr.hp);
- if (max < depth)
- max = depth;
- }
-
- return max + 1;
- }
-
- //赋值广义表
- Status CopyGList(GList *T, GList L)
- {
- if (!L)
- *T = NULL;
- else
- {
- *T = (GList)malloc(sizeof(GLNode));
- if (*T == NULL)
- {
- printf("内存分配失败!\n");
- exit(OVERFLOW);
- }
- (*T)->tag = L->tag;
- if (L->tag == ATOM)
- (*T)->atom = L->atom;
- else
- {
- CopyGList(&((*T)->ptr.hp), L->ptr.hp);
- CopyGList(&((*T)->ptr.tp), L->ptr.tp);
- }
- }
-
- return OK;
- }
-
- //求广义表原子节点的数目
- int CountAtom(GList L)
- {
- int n1, n2;
- if (L == NULL)
- return ERROR;
- if (L->tag == ATOM)
- return 1;
- n1 = CountAtom(L->ptr.hp);
- n2 = CountAtom(L->ptr.tp);
- return n1 + n2;
- }
-
- int main()
- {
- GList L, T;
- SString S;
- char str[60];
-
- printf("请输入广义表:\n");
- cin >> str;
- StrAssign(&S,str);
- CreateList(&L, S);
-
- printf("输出广义表中的元素是:");
- PrintList(L);
- printf("\n");
- GetHead(L);
- GetTail(L);
-
- printf("表的长度为:%d\n",GListLength(L));
- printf("表的深度为:%d\n", GListDepth(L));
- CopyGList(&T, L);
- printf("输出广义表中的元素是:");
- PrintList(T);
- printf("输出广义表中原子节点个数:%d\n",CountAtom(L));
-
- return 0;
- }
-
参考链接:https ://blog.csdn.net/qq_28598203/article/details/51212082
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。