广义表的基本实现
来源:互联网 发布:rcpp软件 编辑:程序博客网 时间:2024/06/05 18:18
广义表是线性表的一种推广。下边通过几个例子说明一下广义表:
A=(),A是一个空表,长度为0,深度为0.
B=(m),B中只有一个元素m,长度为1,深度为1.
C=(a,(b,c),d)有4个元素,长度为4,深度为2.
广义表的存储:
由于广义表的深度我们无法预知,当然不可以采用循环,所以用递归实现咯。
下边来看看实现代码:
#pragma once#include<iostream>using namespace std;#include<assert.h>enum Type{_HEAD_TYPE,_VALUE_TYPE,_SUB_TYPE};struct GeneralizedNode{Type _type;struct GeneralizedNode* _next;union{int _value;struct GeneralizedNode* _sublink;};GeneralizedNode(Type type){_type = type;}};class Generalized{public:Generalized():_head(NULL){}Generalized(char* str):_head(NULL){_head = Create(str);}~Generalized(){_Destroy(_head);}void Print(){_Print(_head);cout << endl;}size_t Size(){size_t count = _Size(_head);return count;}size_t Depth(){size_t depth = _Depth(_head);return depth;}Generalized(const Generalized& g){_head = _Copy(g._head);}//现代写法/*Generalized& operator=(Generalized g){std::swap(_head,g._head);return *this;}*///传统写法Generalized& operator=(const Generalized& g){if (this != &g){GeneralizedNode* head = _Copy(g._head);_Destroy(_head);_head = head;}return *this;}protected:void _Destroy(GeneralizedNode* _head){GeneralizedNode* cur = _head;while (cur){GeneralizedNode* del = cur;if (del->_type == _SUB_TYPE){_Destroy(cur->_sublink);}cur = cur->_next;delete del;}}GeneralizedNode* _Copy(GeneralizedNode* head){GeneralizedNode* cur = head->_next;//遍历原表GeneralizedNode* NewHead = new GeneralizedNode(_HEAD_TYPE);//指向新表GeneralizedNode* pre = NewHead;GeneralizedNode* NewNode;while (cur){if (cur->_type == _SUB_TYPE){NewNode = new GeneralizedNode(_SUB_TYPE);NewNode->_sublink = _Copy(cur->_sublink);pre->_next = NewNode;/*pre = NewNode;cur = cur->_next;*/}else if(cur->_type == _VALUE_TYPE){NewNode = new GeneralizedNode(_VALUE_TYPE);NewNode->_type = _VALUE_TYPE;NewNode->_value = cur->_value;//NewCur->_next = NewNode;pre->_next = NewNode;//NewCur = NewNode;/*NewCur = NewCur->_next;*//*pre = pre->_next;cur = cur->_next;*/}cur = cur->_next;pre = pre->_next;}pre->_next = NULL;return NewHead;}size_t _Depth(GeneralizedNode* head){GeneralizedNode* cur = head;size_t maxDepth = 1;while (cur){size_t depth = 1;if (cur->_type == _SUB_TYPE){depth = _Depth(cur->_sublink)+1;if (depth > maxDepth){maxDepth = depth;}}cur = cur->_next;}return maxDepth;}void _Print(GeneralizedNode* head){cout << "(";GeneralizedNode* cur = head;while (cur){if (cur->_type == _VALUE_TYPE){cout << cur->_value;if (cur->_next != NULL){cout << ",";}cur = cur->_next;}else if (cur->_type == _SUB_TYPE){_Print(cur->_sublink);if (cur->_next != NULL){cout << ",";}cur = cur->_next;}else{cur = cur->_next;}}cout << ")";}size_t _Size(GeneralizedNode* &head){GeneralizedNode* cur = head;size_t count = 0;while (cur){if (cur->_type == _VALUE_TYPE){++count;cur = cur->_next;}else if (cur->_type == _SUB_TYPE)//子表{count += _Size(cur->_sublink);cur = cur->_next;}else{cur = cur->_next;}}return count;}bool isValue(char c){//if (isalpha(c))//小写字母,大写字母if((c >= 'a'&&c<= 'z')|| (c >= 'A'&&c <= 'Z'))return true;elsereturn false;}GeneralizedNode* Create(char* &str){assert(*str == '(');str++;GeneralizedNode* head = new GeneralizedNode(_HEAD_TYPE);GeneralizedNode* prev = head;GeneralizedNode* cur = NULL;head->_next = cur;while (*str){if (isValue(*str))//字母字符{cur = new GeneralizedNode(_VALUE_TYPE);cur->_value = *str;prev->_next = cur;str++;prev = cur;}else if (*str == '('){GeneralizedNode* pLink = new GeneralizedNode(_SUB_TYPE);prev->_next = pLink;//cur = cur->_next;cur = Create(str);pLink->_sublink = cur;prev = pLink;}else if (*str == ')'){prev->_next = NULL;str++;return head;}else{str++;}}return head;}public:GeneralizedNode* _head;};void TestGeneralized(){Generalized s1("()");Generalized s2("(a,b)");Generalized s3("(a,b,(c,d))");Generalized s4("(a,b,(c,d),e)");Generalized s5("(a,b,(c,(),d),e)");Generalized s6(s3);s1 = s2;s1.Print();s2.Print();s3.Print();s4.Print();s6.Print();cout << s1.Size() << endl;cout << s2.Size() << endl;cout << s3.Size() << endl;cout << s4.Size() << endl;cout << s1.Depth() << endl;cout << s2.Depth() << endl;cout << s3.Depth() << endl;cout << s4.Depth() << endl;cout << s5.Depth() << endl;}
结点的定义中使用了枚举类型,原因如下:
结点有三种类型,值类型,头结点类型和子表 结点类型,而这三种结点公共的属性就是
每个结点都有自己的type(类型),也有自己的next域,值结点有自己的value,子表结
点有自己的_sublink,所以,这个可以定义成共用体类型,节省空间。
由于广义表需要用到递归,而类的成员函数最好不要递归(因为类的成员函数是内联函
数)
内联函数的特点:
在函数的调用处直接展开,减少了函数调用过程中的压栈开销所以,代码很长或者有
循环,递归就尽量不要内联。
内联对于编译器而言只是一个建议,编译器会自动优化,如果内联函数内有循环或者
递归,编译器会忽略内联。
inline必须和函数的定义放在一起。
下边再来简述一下operator=函数
两种实现办法:
传统的方法 ------避免自赋值;先构造,再释放(防止构造时申请空间失败)
现代写法------一种是代码中写的那样
交换之后,原来空间的内容就会保存在那个形参变量中,离开作用域自动 析构
--------另一种是传引用。代码如下:
<pre name="code" class="cpp">GeneralizedNode* operator=(const Generalized& g){ if(&g != this) { Generalized<T> tmp(g); swap(_head,tmp._head); }return *this;}
好了,广义表就到这里~~~
1 0
- 广义表的基本实现
- 广义表的基本操作实现
- 实现广义表的基本运算
- 实现广义表的各种基本运算算法
- 数组和广义表的基本运算实现
- 数据结构 - 数组和广义表的基本运算实现
- 广义表的实现
- 广义表的实现
- 广义表的实现
- 广义表的实现
- 广义表的基本操作
- 广义表的基本操作
- 广义表的基本操作
- 广义表的递归实现
- 广义表的递归实现
- 广义表的简单实现
- 广义表的简单实现
- 【数据结构】广义表的实现
- C语言 1~100 所有整数中出现多少次数字 9
- 第4周项目3-并联电阻
- AndroidStudio导入一个AndroidStudio工程作为一个Library Module
- 实验二任务1打招呼
- TCP发送源码学习(3)--tcp_transmit_skb
- 广义表的基本实现
- 设计模式
- struts2.5以上 报方法不允许错误
- property not initialized at super.init call
- anaconda安装opencv
- (排列生成算法)枚举排列的两种方法:递归枚举和next_permutation (使用多用next_permutation)
- as plugin GsonFormat
- 详述mysql的子查询及其常用使用方法
- 什么是多线程?线程的生命周期?