广义表的定义
广义表是非线性的结构,是线性表的一种扩展,是有n个元素组成有限序列。
广义表的定义是递归的,因为在表的描述中又得到了表,允许表中有表。
例如
<1> A = ()
<2> B = (a,b)
<3> C = (a,b,(c,d))
<4> D = (a,b,(c,d),(e,(f),h))
<5> E = (((),())
小小分析:
首先得定义节点类。
其次,除了正常的数据项之外,还得考虑子节点。
当然,不管表的节点,还是子节点都不存数据,存下一数据项的地址。
广义表的节点结构定义:
enum Type
02.{
03. HEAD,//头结点
04. VALUE,//数据
05. SUB,//子表
06.};
07.
08.//广义表结构
09.struct GeneralizedNode
10.{
11.public:
12. //无参构造函数
13. GeneralizedNode()
14. :_type(HEAD)
15. ,_next(NULL)
16. {}
17.
18. //有参的构造函数
19. GeneralizedNode(Type type, char ch);
20.
21.public:
22. Type _type;
23. GeneralizedNode* _next;
24.
25. //因为节点类型不可能既是数据节点又是子表结点,所以采用联合结构,
26. //节省空间,便于管理。
27. union
28. {
29. char _value;//数据结点
30. GeneralizedNode* _subLink;//子表结点
31. };
32.};
33.
34.//有参的构造函数
35.GeneralizedNode::GeneralizedNode(Type type, char ch = 0)
36. :_type(type)
37. , _next(NULL)
38.{
39. //数据节点则为数据初始化
40. if (_type == VALUE)
41. {
42. _value = ch;
43. }
44. //子表结点的初始化
45. else if (_type == SUB)
46. {
47. _subLink = NULL;
48. }
49.}
广义表的定义:
注意:由于广义表的采用的是用递归实现。但构造函数,等成员函数不能够采用递归,而且在函数内部需要不断的传子表的head,对于成员函数直接使用成员变量_head,则无法递归下去。
- //广义表类
- class Generalized
- {
- public:
- //无参构造函数
- Generalized()
- :_head(new GeneralizedNode(HEAD))
- {}
- //有参构造函数
- Generalized(const char* str)
- :_head(NULL)
- {
- _head = CreateList(str);
- }
- //拷贝构造函数
- Generalized(const Generalized& g)
- {
- _head=_CopyList(g._head);
- }
- GeneralizedNode* _CopyList(GeneralizedNode* head);
- //赋值运算符的重载
- Generalized& operator=(Generalized g)
- {
- swap(_head, g._head);
- return *this;
- }
- //析构函数
- ~Generalized()
- {
- _Delete(_head);
- }
- void _Delete(GeneralizedNode* head);
- public:
- //打印广义表
- void Print()
- {
- _Print(_head);
- }
- //求广义表的大小
- size_t Size()
- {
- return _Size(_head);
- }
- //求广义表的深度
- size_t Depth()
- {
- return _Depth(_head);
- }
- protected:
- //判断数据是否有效
- bool IsVaild(const char ch);
- //创建广义表
- GeneralizedNode* CreateList(const char* &str);
- void _Print(GeneralizedNode* head);
- size_t _Size(GeneralizedNode* head);
- size_t _Depth(GeneralizedNode* head);
- private:
- GeneralizedNode* _head;
- };
函数的实现
GeneralizedNode* Generalized::_CopyList(GeneralizedNode* head) 02.{ 03. GeneralizedNode* cur = head;//需要拷贝的广义表的当前节点 04. GeneralizedNode* _head = new GeneralizedNode();//拷贝广义表的头结点 05. GeneralizedNode* index = _head;//拷贝广义表的当前节点 06. while (cur) 07. { 08. //数据结点 09. if (cur->_type == VALUE) 10. { 11. index->_next = new GeneralizedNode(VALUE, cur->_value); 12. index = index->_next; 13. } 14. //子表结点,递归复制 15. else if (cur->_type == SUB) 16. { 17. GeneralizedNode*SubNode = new GeneralizedNode(SUB); 18. index->_next = SubNode; 19. SubNode->_subLink= _CopyList(cur->_subLink); 20. index = index->_next; 21. } 22. cur = cur->_next; 23. } 24. return _head; 25.} 26. 27.void Generalized::_Delete(GeneralizedNode* head) 28.{ 29. GeneralizedNode* cur = head; 30. while (cur) 31. { 32. GeneralizedNode* del = cur; 33. //递归删除子表 34. if (cur->_type == SUB) 35. { 36. _Delete(cur->_subLink); 37. } 38. cur = cur->_next; 39. delete del; 40. } 41.} 42. 43.//判断广义表的数据是否合法 44.bool Generalized::IsVaild(const char ch) 45.{ 46. if ((ch >= '0'&&ch <= '9') 47. || (ch >= 'a'&&ch <= 'z') 48. || (ch >= 'A'&&ch <= 'Z')) 49. { 50. return true;//合法 51. } 52. return false;//非法 53.} 54. 55.GeneralizedNode* Generalized::CreateList(const char* &str) 56.{ 57. assert(str &&*str == '(');//断言防止传的广义表格式不对,或者为空 58. str++;//跳过第一个( 59. 60. GeneralizedNode* head = new GeneralizedNode();//创建头结点 61. GeneralizedNode* cur = head; 62. while (*str) 63. { 64. if (IsVaild(*str)) 65. { 66. 67. 68. cur->_next = new GeneralizedNode(VALUE, *str); 69. cur = cur->_next; 70. str++; 71. } 72. else if (*str == '(')//新的子表 73. { 74. GeneralizedNode* SubNode = new GeneralizedNode(SUB); 75. SubNode->_subLink = CreateList(str); 76. cur->_next = SubNode; 77. cur = cur->_next; 78. } 79. else if (*str == ')')//广义表结束 80. { 81. str++;//返回之前需要给str++指向下一个 82. return head; 83. } 84. else//空格或者逗号 85. { 86. str++; 87. } 88. } 89. 90. assert(false); 91. return NULL; 92.} 93. 94.void Generalized::_Print(GeneralizedNode* head) 95.{ 96. GeneralizedNode* cur = head; 97. if (cur == NULL) 98. { 99. cout << "()" << endl; 100. return; 101. } 102. 103. while (cur) 104. { 105. if (cur->_type == HEAD) 106. { 107. cout << "("; 108. } 109. else if (cur->_type == VALUE) 110. { 111. cout << cur->_value; 112. //_value不是最后一个值 113. if (cur->_next) 114. { 115. cout << ","; 116. } 117. } 118. else if (cur->_type == SUB) 119. { 120. _Print(cur->_subLink); 121. if (cur->_next) 122. { 123. cout << ","; 124. } 125. } 126. cur = cur->_next; 127. } 128. //输出每个表最后一个( 129. cout << ")"; 130.} 131. 132. 133.size_t Generalized::_Size(GeneralizedNode* head) 134.{ 135. GeneralizedNode* cur = head; 136. size_t count = 0; 137. while (cur) 138. { 139. if (cur->_type == VALUE) 140. { 141. count++; 142. } 143. //递归求取子表的大小 144. if (cur->_type == SUB) 145. { 146. count = count + _Size(cur->_subLink); 147. } 148. cur = cur->_next; 149. } 150. return count; 151.} 152. 153. 154.size_t Generalized::_Depth(GeneralizedNode* head) 155.{ 156. GeneralizedNode* cur = head; 157. size_t depth = 1;//空表深度为1 158. while (cur) 159. { 160. if (cur->_type == SUB) 161. { 162. size_t newDepth = _Depth(cur->_subLink); 163. //如果子表的深度+1大于当前广义表的最大深度,则更新广义表的深度 164. if (newDepth +1 > depth) 165. { 166. depth = newDepth + 1; 167. } 168. } 169. cur = cur->_next; 170. } 171. return depth; 172.}
测试代码
<div class="bar"><div class="tools"><strong></strong><div style="left: 416px; top: 7216px; width: 18px; height: 18px; position: absolute; z-index: 99;"></div><span data-mod="popu_169"><strong>
</strong></span></div></div><ol class="dp-cpp"><li class="alt"><span><span class="preprocessor">#include"Generalized.h"</span><span> </span></span></li><li><span> </span></li><li class="alt"><span><span class="keyword">void</span><span> TestGeneralized() </span></span></li><li><span>{ </span></li><li class="alt"><span> Generalized l(<span class="string">"(a,b,(c,d),(e,(f),h))"</span><span>); </span></span></li><li><span> Generalized l1; </span></li><li class="alt"><span> l1 = l; </span></li><li><span> l.Print(); </span></li><li class="alt"><span> cout << endl; </span></li><li><span> cout << <span class="string">"size:"</span><span> << l.Size() << endl; </span></span></li><li class="alt"><span> cout << <span class="string">"depth:"</span><span> << l.Depth() << endl; </span></span></li><li><span> </span></li><li class="alt"><span> l1.Print(); </span></li><li><span> cout << endl; </span></li><li class="alt"><span> cout << <span class="string">"size:"</span><span> << l1.Size() << endl; </span></span></li><li><span> cout << <span class="string">"depth:"</span><span> << l1.Depth() << endl; </span></span></li><li class="alt"><span>} </span></li><li><span><span class="datatypes">int</span><span> main() </span></span></li><li class="alt"><span>{ </span></li><li><span> TestGeneralized(); </span></li><li class="alt"><span> getchar(); </span></li><li><span> <span class="keyword">return</span><span> 0; </span></span></li><li class="alt"><span>} </span></li></ol>
测试结果