广义表的定义、存储结构

目录

一、广义表的定义

1.1定义

1.2相关概念

1.3性质

 1.4基本运算

二、广义表的存储结构

2.1头尾链表的存储结构

2.2扩展线性链表的存储结构


一、广义表的定义

1.1定义

广义表是n>=0个元素a0,a1,....,a(n-1)的有限序列,其中每一个a(i)或者是原子,或者是一个广义表。(拓宽了的线性表)

1.2相关概念

①记法:LS=(a1,a2,..,a(n))

LS为表名,n为表的长度,每一个a(i)为表的元素。

(一般用大写字母表示广义表小写字母表示原子)

②表头:LS非空的第一个元素a(i),记作head(LS)=a1

(表头可以是原子,也可以是子表)

③表尾:除表头之外的其他元素组成的,记作tail(LS)=(a2,...,a(n))

(表尾不是最后一个元素,而是一个子表)

例:

①A=()    ——>空表,长度为0

②B=(())  ——>长度为1,表头、表尾均为()

③C=(a,(b,c)) ——>长度为2,由原子a和子表(b,c)构成;表头为a,表尾为((b,c)) (由(b,c)这个广义表组成的一个广义表)

④D=(x,y,z) ——>长度为3,每一项都是原子;表头为x,表尾为(y,z)

⑤E=(C,D) ——>长度为2,每一项都是子表;表头为C,表尾为(D)   (共享广义表)

⑥F=(a,F)  ——>长度为2,第一项为原子,第二项为它本身;表头为a,表尾为(F) (递归广义表)F=(a1(a1(a1,....)))

1.3性质

①广义表中的数据元素有相对次序;一个直接前驱和一个直接后继

②广义表的长度定义为最外层所包含元素的个数

如:C=(a,(b,c))是长度为2的广义表

③广义表的深度定义为该广义表展开后所含括号的重数

如:A=(b,c)的深度为1,B=(A,d)的深度为2,C=(f,B,h)的深度为3

注:原子的深度为0,空表的深度为1。

④广义表可以为其他广义表共享,如上述例子B就共享A,B=(A)

⑤广义表可以是一个递归的表。如上述例子F=(a,F)=(a1(a1(a1,...)))

注:递归表的深度是无穷值,长度时有限值。

⑥广义表是多层次结构,元素可以是单元素,也可以是子表,而子表的元素还可以是子表。

可以用图形象地表示:

 1.4基本运算

①求表头GetHead(L)  表头可以是一个单原子,也可以是一个子表

②求表尾GetTail(L)  表尾一定是一个表

二、广义表的存储结构

2.1头尾链表的存储结构

①表结点:标志域、指示表头的指针域、指示表尾的指针域。

tag=1hptp

 ②原子结点:标志域和值域

tag=0atom

形式定义:

typedef enum{ATOM,LIST} ElemTag;   //ATOM==0:原子;LIST==1:子表
typedef struct GLNode{
  ElemTag tag;                    //公共部分,用于区分原子结点和表结点
  union                           //原子结点和表结点的联合部分
  {
     AtomType atom;               //atom是原子结点的值域
     struct{struct GLNode*hp,*tp;}ptr; //ptr是表结点的指针域,ptr.hp和ptr.tp分别指向表头和表尾
  };
}*GList;                          //广义表类型
   

2.2扩展线性链表的存储结构

在这种结构中,无论是表结点还是原子结点,均由3个域组成

①表结点

tag=1hptp

②原子结点

tag=0atomtp

 

  • 29
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是C++语言实现广义表存储结构(链式存储)以及常用功能的示例代码: ``` // 定义广义表节点 template <typename T> struct GLNode { bool is_list; // 标识当前节点是否为子表 union { T data; // 当前节点为原子时,存储原子值 GLNode<T>* link; // 当前节点为子表时,指向子表第一个节点 } val; GLNode<T>* next; // 指向下一个节点 GLNode(bool flag = false):is_list(flag), next(nullptr){} // 构造函数 }; // 定义广义表类 template <typename T> class GList { public: GList():head(nullptr){} // 构造函数 ~GList(){destroy(head);} // 析构函数 GLNode<T>* create_list(const std::string& s); // 从字符串生成广义表 void print_list(GLNode<T>* p); // 打印广义表 int depth(GLNode<T>* p); // 求广义表深度 int length(GLNode<T>* p); // 求广义表长度 void destroy(GLNode<T>*& p); // 销毁广义表 private: GLNode<T>* head; // 指向广义表头节点 GLNode<T>* create_node(); // 创建广义表节点 }; // 创建广义表节点 template <typename T> GLNode<T>* GList<T>::create_node() { GLNode<T>* p = new GLNode<T>(); if (!p) exit(1); return p; } // 从字符串生成广义表 template <typename T> GLNode<T>* GList<T>::create_list(const std::string& s) { std::stack<GLNode<T>*> st; // 用栈来辅助生成广义表 GLNode<T>* p = nullptr; int i = 0; while (i < s.size()) { switch (s[i]) { case '(': p = create_node(); st.push(p); if (!head) head = p; break; case ')': if (!st.empty()) { st.pop(); if (st.empty()) return head; // 如果栈为空则生成完毕,返回表头 } break; case ',': break; default: p = create_node(); if (s[i] == '#') { p->is_list = true; i++; } else { p->is_list = false; } std::stringstream ss; while (i < s.size() && s[i] != '(' && s[i] != ')' && s[i] != ',') { ss << s[i]; i++; } ss >> p->val.data; i--; if (!st.empty()) { GLNode<T>* q = st.top(); if (!q->val.link) q->val.link = p; else { GLNode<T>* t = q->val.link; while (t->next) t = t->next; t->next = p; } } break; } i++; } return head; } // 打印广义表 template <typename T> void GList<T>::print_list(GLNode<T>* p) { if (!p) return; if (p->is_list) { std::cout << "#("; GLNode<T>* q = p->val.link; while (q) { print_list(q); if (q->next) std::cout << ","; q = q->next; } std::cout << ")"; } else { std::cout << p->val.data; } } // 求广义表深度 template <typename T> int GList<T>::depth(GLNode<T>* p) { if (!p) return 0; if (!p->is_list) return 0; int max_depth = 0; GLNode<T>* q = p->val.link; while (q) { max_depth = std::max(max_depth, depth(q)); q = q->next; } return max_depth + 1; } // 求广义表长度 template <typename T> int GList<T>::length(GLNode<T>* p) { if (!p) return 0; int len = 0; if (p->is_list) { GLNode<T>* q = p->val.link; while (q) { len += length(q); q = q->next; } } else { len = 1; } return len; } // 销毁广义表 template <typename T> void GList<T>::destroy(GLNode<T>*& p) { if (!p) return; if (p->is_list) { GLNode<T>* q = p->val.link; while (q) { GLNode<T>* t = q->next; destroy(q); q = t; } } delete p; p = nullptr; } ``` 示例用法: ``` int main() { GList<int> gl; GLNode<int>* head = gl.create_list("(1,2,3,(4,5,#(6,7,8)),9)"); gl.print_list(head); std::cout << std::endl; std::cout << "Depth: " << gl.depth(head) << std::endl; std::cout << "Length: " << gl.length(head) << std::endl; gl.destroy(head); return 0; } ``` 输出结果: ``` 1,2,3,(4,5,#(6,7,8)),9 Depth: 3 Length: 9 ```

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值