javascript实现数据结构:广义表

原文:javascript实现数据结构:广义表

 广义表是线性表的推广。广泛用于人工智能的表处理语言Lisp,把广义表作为基本的数据结构。

广义表一般记作:

LS = (a1, a2, ..., an)

LS是广义表的名称,n是它的长度,ai可以是单个元素,也可以是广义表,分别称为广义表LS的原子子表。习惯上,用大写字母表示广义表的名称,小写字母表示原子。当广义表LS非空时,称第一个元素a1为LS的表头,称其余元素组成的表(a2,
a3, ..., an)是LS的表尾

下面列举一些广义表的例子:

1.A = () ---- A是一个空表,它的长度为0。

2.B = (e) ---- 列表B只有一个原子e,B的长度为1。

3.C = (a, (b, c, d)) ---- 列表C的长度为2,两个元素分别为原子a和子表(b, c, d)。

4.D = (A, B, C) ---- 列表D的长度为3,3个元素都是列表。显示,将子表的值代入后,则有D = ((), (e), (a, (b, c,
d)))。

5.E = (a, E) ---- 这是一个递归的表,它的长度为2.E相当于一个无限的列表E = (a, (a, (a, ...)))。

下图为列表的图形表示:

从定义和例子可推出三个结论:

1)列表的元素可以是子表,而子表的元素还可以是子表。由此,列表是一个多层次的结构,可以用图形象地表示。

2)列表可为其它列表所共享。列表A,B和C为D的子表,则在D中可以不必列出子表的值。

3)列表可以是一个递归的表,即列表也可以是其本身的一个子表。例如列表E。

然后我们根据结论可知:

任何一个非空列表其表头可能是原子,也可能是列表,而其表尾必定为列表。

由于广义表中的数据元素可以具有不同的结构(或是原子,或是列表),因此难以用顺序存储结构表示,通常采用链式存储结构,每个数据元素可用一个结点表示。

下面是两种稍微不同的存储结构表示:


 1 var ATOM = 0;
2 var LIST = 1;
3
4 // 广义表的头尾链表存储表示
5 function GLNode() {
6 // 公共部分,用于区分原子结点和表结点
7 this.tag = undefined;
8
9 // atom是原子结点的值域
10 this.atom = null;
11 // ptr是表结点的指针域
12 this.ptr = {
13 // ptr.hp和ptr.tp分别指向表头和表尾
14 hp: null,
15 tp: null
16 };
17 }
18
19 // 广义表的扩展线性链表存储表示
20 function GLNode2() {
21 // 公共部分,用于区分原子结点和表结点
22 this.tag = undefined;
23
24 // 原子结点的值域
25 this.atom = null;
26 // 表结点的表头指针
27 this.hp = null;
28
29 // 相当于线性链表的next,指向下一个元素结点
30 this.tp = null;
31 }

下列分别为两个存储结构的示例图:

1.GLNode

2.GLNode2

两种存储结构没有大的区别,可根据自己的习惯选择。

广义表的递归算法

我们知道递归定义的归纳项是用来描述如何实现从当前状态到终结状态的转化。

由于递归函数的设计用的是归纳思维的方法,则在设计递归函数时,应注意:
(1)首先应书写函数的首部和规格说明,严格定义函数的功能和接口(递归调用的界面),对求精函数中所得的和原问题性质相同的字问题,只要接口一致,便可进行递归调用。
(2)对函数中的每一个递归调用都看成只是一个简单的操作,只要接口一致,必能实现规格说明中定义的功能,切忌想得太深太远。

求广义表的深度

广义表的深度定义为广义表中括弧的重数,是广义表的一种量度。
设非空广义表为:
    LS = (a1, a2, ...,
an)

其中ai(i = 1, 2, ...,
n)或为原子或为LS的子表,则求LS的深度可分解为n个子问题,每个子问题为求ai的深度,若ai是原子,则由定义其深度为零,若ai是广义表,则递归处理,而LS的深度为各ai(i
= 1, 2, ..., n)的深度最大值加1.空表也是广义表,且深度为1.

广义表的深度DEPTH(LS)的递归定义为:
    基本项: DEPTH(LS) = 1
当LS为空表时
               
 DEPTH(LS) = 0 当LS为原子时
    归纳项: DEPTH(LS) = 1 +
MAX{DEPTH(ai)} 1 <= i <= n

下面为采用头尾链表存储结构,求广义表的深度的代码:


 1 // 采用头尾链表存储结构,求广义表的深度
2 GLNode.prototype.depth = function () {
3 return getDepth(this);
4 };
5
6 function getDepth(gList) {
7 if (!gList) return 1;
8 else if (gList.tag === ATOM) return 0;
9
10 var m = getDepth(gList.ptr.hp) + 1;
11 var n = getDepth(gList.ptr.tp);
12
13 return m > n ? m : n;
14 }

然后下面是广义表基本操作的代码(都是涉及到递归算法设计):


  1 // 复制广义表
2 GLNode.prototype.copyList = function (gList) {
3 gList.tag = this.tag;
4
5 if (this.tag === ATOM) {
6 gList.atom = this.atom;
7 } else {
8 if (this.ptr.hp) {
9 gList.ptr.hp = new GLNode();
10 this.copyList.call(this.ptr.hp, gList.ptr.hp);
11 }
12 if (this.ptr.tp) {
13 gList.ptr.tp = new GLNode();
14 this.copyList.call(this.ptr.tp, gList.ptr.tp);
15 }
16 }
17 };
18
19 function isWord(str){
20 return /^[\w-]+$/.test(str);
21 }
22
23 // 采用头尾链表存储结构,由广义表的书写形式串创建广义表
24 GLNode.prototype.createGList = function (string) {
25 string = string.trim();
26
27 // 创建单原子广义表
28 var q;
29 if (isWord(string)) {
30 this.tag = ATOM;
31 this.atom = string;
32 } else {
33 this.tag = LIST;
34 var p = this;
35
36 // 脱外层括号
37 var sub = string.substr(1, string.length - 2);
38
39 do {
40 var hsub;
41 var n = sub.length;
42 var i = 0;
43 var k = 0;
44 var ch;
45
46 do {
47 ch = sub[i++];
48 if (ch == ‘(‘) ++k;
49 else if (ch == ‘)‘) --k;
50 } while (i < n && (ch != ‘,‘ || k != 0));
51
52 // i为第一个逗号分隔索引
53 if (i < n) {
54 hsub = sub.substr(0, i - 1);
55 sub = sub.substr(i, n - i);
56
57 // 最后一组
58 } else {
59 hsub = sub;
60 sub = ‘‘;
61 }
62
63 if(hsub === ‘()‘)
64 p.ptr.hp = null;
65 else
66 // 创建表头结点
67 this.createGList.call((p.ptr.hp = new GLNode()), hsub);
68
69 q = p;
70
71 // 创建表尾结点
72 if (sub) {
73 p = new GLNode();
74 p.tag = LIST;
75 q.ptr.tp = p;
76 }
77 } while (sub);
78
79 q.ptr.tp = null;
80 }
81 };
82
83 var node = new GLNode();
84 node.createGList(‘((), (ea), (sa, (bd, ce, dh)))‘);
85 console.log(node.depth());
86
87 GLNode.equal = function equal(gList1, gList2) {
88 // 空表时相等的
89 if (!gList1 && !gList2) return true;
90 if (gList1.tag === ATOM && gList2.tag === ATOM && gList1.atom === gList2.atom) return true;
91
92 if (gList1.tag === LIST && gList2.tag === LIST) {
93 // 表头表尾都相等
94 if (equal(gList1.ptr.hp, gList2.ptr.hp) && equal(gList1.ptr.tp, gList2.ptr.tp)) return true;
95 }
96
97 return false;
98 };
99
100 // 递归逆转广义表
101 GLNode.prototype.reverse = function reverse() {
102 var ptr = [];
103 // 当A不为原子且表尾非空时才需逆转
104 if (this.tag === LIST && this.ptr.tp) {
105 for (var i = 0, p = this; p; p = p.ptr.tp, i++) {
106 // 逆转各子表
107 if (p.ptr.hp) reverse.call(p.ptr.hp);
108
109 ptr[i] = p.ptr.hp;
110 }
111
112 // 重新按逆序排列各子表的顺序
113 for (p = this; p; p = p.ptr.tp)
114 p.ptr.hp = ptr[--i];
115 }
116 };
117
118 var global = Function(‘return this‘)();
119 GLNode.prototype.toString = function () {
120 var str = ‘‘;
121 if (this == global) str = ‘()‘;
122 else if (this.tag === ATOM) str = this.atom; // 原子
123 else {
124 str += ‘(‘;
125
126 for (var p = this; p; p = p.ptr.tp) {
127 str += this.toString.call(p.ptr.hp);
128 if (p.ptr.tp) str += ‘, ‘;
129 }
130 str += ‘)‘;
131 }
132
133 return str;
134 };
135
136 // 按层序输出广义表
137 // 层序遍历的问题,一般都是借助队列来完成的,每次从队头
138 // 取出一个元素的同时把它下一层的孩子插入队尾,这是层序遍历的基本思想
139 GLNode.prototype.orderPrint = function(){
140 var queue = [];
141 for(var p = this; p; p = p.ptr.tp) queue.push(p);
142
143 while(queue.length){
144 var r = queue.shift();
145 if(r.tag === ATOM) console.log(r.atom);
146 else {
147 for(r = r.ptr.hp; r; r = r.ptr.tp)
148 queue.push(r);
149 }
150 }
151 };
152
153 // 使用链队列
154 var Queue = require(‘../Queue/Queue.js‘).Queue;
155 GLNode.prototype.orderPrint2 = function(){
156 var queue = new Queue();
157
158 for(var p = this; p; p = p.ptr.tp) queue.enQueue(p);
159
160 while(queue.size){
161 var r = queue.deQueue();
162 if(r.tag === ATOM) console.log(r.atom);
163 else {
164 for(r = r.ptr.hp; r; r = r.ptr.tp)
165 queue.enQueue(r);
166 }
167 }
168 };
169
170 console.log(node + ‘‘);
171 node.reverse();
172 console.log(node + ‘‘);
173
174 var node2 = new GLNode();
175 node.copyList(node2);
176 console.log(GLNode.equal(node, node2));
177
178 console.log(node + ‘‘);
179 console.time(‘A‘);
180 node.orderPrint();
181 console.timeEnd(‘A‘);
182
183 console.log(‘------------------------------------‘);
184 console.time(‘B‘);
185 node.orderPrint2();
186 console.timeEnd(‘B‘);

广义表的运用:

m元多项式表示

如果用线性表来表示,则每个数据元素需要m+1个数据项,以存储一个系数和m个指数值,这将产生两个问题。
一是无论多项式中各项的变元数是多是少,若都按m个变元分配存储空间,则将造成浪费;反之,若按各项实际的变元数分配存储空间,就会造成结点的大小不匀,给操作带来不便。二是对m值不同的多项式,线性表中的结点大小也不同,这同样引起存储管理的不便。
故不适于用线性表表示。

例如三元多项式:
    P(x, y, z) = x(10)y(3)z(2) + 2x(6)y(3)z(2) +
3x(5)y(2)z(2) + x(4)y(4)z + 2yz + 15

如若改写为:
    P(x, y, z) = ((x(10) + 2x(6))y(3) + 3x(5)y(2))z(2) +
((x(4) + 6x(3))y(4) + 2y)z + 15

用广义表表示:
    P = z((A, 2), (B, 1), (15, 0))
    A =
y((C, 3), (D, 2))
    B = y((E, 4), (F, 1))
    C =
x((1, 10), (2, 6))
    D = x((3, 5))
    E = x((1, 4),
(6, 3))
    F = x((2, 0))

下面为用广义表描述m元多项式的存储结构:


 1 function MPNode() {
2 // 区分原子结点和表结点
3 this.tag = undefined;
4 // 指数域
5 this.exp = 0;
6
7 // 系数域
8 this.coef = 0;
9 // 表结点的表头指针
10 this.hp = null;
11
12 // 相当于线性表的next,指向下一个元素结点
13 this.tp = null;
14 }

篇幅有限,就没有做其他操作,以后有空再补回吧。

所有代码:

  1 /**
2 * 广义表
3 *
4 * 广义表是线性表的推广。广泛用于人工智能的表处理语言Lisp,把广义表作为基本的数据结构。
5 * 广义表一般记作:
6 * LS = (a1, a2, ..., an)
7 * LS是广义表的名称,n是它的长度,ai可以是单个元素,也可以是广义表,分别称为广义表LS的原子和子表。习惯上,用大写字母表示广义表的名称,小写字母表示原子。当广义表LS非空时,称第一个元素a1为LS的表头,称其余元素组成的表(a2, a3, ..., an)是LS的表尾。
8 *
9 * 下面列举一些广义表的例子:
10 * 1.A = () ---- A是一个空表,它的长度为0。
11 * 2.B = (e) ---- 列表B只有一个原子e,B的长度为1。
12 * 3.C = (a, (b, c, d)) ---- 列表C的长度为2,两个元素分别为原子a和子表(b, c, d)。
13 * 4.D = (A, B, C) ---- 列表D的长度为3,3个元素都是列表。显示,将子表的值代入后,则有D = ((), (e), (a, (b, c, d)))。
14 * 5.E = (a, E) ---- 这是一个递归的表,它的长度为2.E相当于一个无限的列表E = (a, (a, (a, ...)))。
15 *
16 * 1)列表的元素可以是子表,而子表的元素还可以是子表。由此,列表是一个多层次的结构,可以用图形象地表示。
17 * 2)列表可为其它列表所共享。列表A,B和C为D的子表,则在D中可以不必列出子表的值。
18 * 3)列表可以是一个递归的表,即列表也可以是其本身的一个子表。例如列表E。
19 *
20 * 任何一个非空列表其表头可能是原子,也可能是列表,而其表尾必定为列表。
21 *
22 */
23
24 var ATOM = 0;
25 var LIST = 1;
26
27 // 广义表的头尾链表存储表示
28 function GLNode() {
29 // 公共部分,用于区分原子结点和表结点
30 this.tag = undefined;
31
32 // atom是原子结点的值域
33 this.atom = null;
34 // ptr是表结点的指针域
35 this.ptr = {
36 // ptr.hp和ptr.tp分别指向表头和表尾
37 hp: null,
38 tp: null
39 };
40 }
41
42 // 广义表的扩展线性链表存储表示
43 function GLNode2() {
44 // 公共部分,用于区分原子结点和表结点
45 this.tag = undefined;
46
47 // 原子结点的值域
48 this.atom = null;
49 // 表结点的表头指针
50 this.hp = null;
51
52 // 相当于线性链表的next,指向下一个元素结点
53 this.tp = null;
54 }
55
56
57 /*
58 广义表的递归算法
59
60 递归定义的归纳项描述了如何实现从当前状态到终结状态的转化。
61
62 由于递归函数的设计用的是归纳思维的方法,则在设计递归函数时,应注意:
63 (1)首先应书写函数的首部和规格说明,严格定义函数的功能和接口(递归调用的界面),对求精函数中所得的和原问题性质相同的字问题,只要接口一致,便可进行递归调用。
64 (2)对函数中的每一个递归调用都看成只是一个简单的操作,只要接口一致,必能实现规格说明中定义的功能,切忌想得太深太远。
65 */
66
67 /*
68 求广义表的深度
69
70 广义表的深度定义为广义表中括弧的重数,是广义表的一种量度。
71 设非空广义表为:
72 LS = (a1, a2, ..., an)
73
74 其中ai(i = 1, 2, ..., n)或为原子或为LS的子表,则求LS的深度可分解为n个子问题,每个子问题为求ai的深度,若ai是原子,则由定义其深度为零,若ai是广义表,则递归处理,而LS的深度为各ai(i = 1, 2, ..., n)的深度最大值加1.空表也是广义表,且深度为1.
75
76 广义表的深度DEPTH(LS)的递归定义为:
77 基本项: DEPTH(LS) = 1 当LS为空表时
78 DEPTH(LS) = 0 当LS为原子时
79 归纳项: DEPTH(LS) = 1 + MAX{DEPTH(ai)} 1 <= i <= n
80 */
81
82 // 采用头尾链表存储结构,求广义表的深度
83 GLNode.prototype.depth = function () {
84 return getDepth(this);
85 };
86
87 function getDepth(gList) {
88 if (!gList) return 1;
89 else if (gList.tag === ATOM) return 0;
90
91 var m = getDepth(gList.ptr.hp) + 1;
92 var n = getDepth(gList.ptr.tp);
93
94 return m > n ? m : n;
95 }
96
97 // 复制广义表
98 GLNode.prototype.copyList = function (gList) {
99 gList.tag = this.tag;
100
101 if (this.tag === ATOM) {
102 gList.atom = this.atom;
103 } else {
104 if (this.ptr.hp) {
105 gList.ptr.hp = new GLNode();
106 this.copyList.call(this.ptr.hp, gList.ptr.hp);
107 }
108 if (this.ptr.tp) {
109 gList.ptr.tp = new GLNode();
110 this.copyList.call(this.ptr.tp, gList.ptr.tp);
111 }
112 }
113 };
114
115 function isWord(str){
116 return /^[\w-]+$/.test(str);
117 }
118
119 // 采用头尾链表存储结构,由广义表的书写形式串创建广义表
120 GLNode.prototype.createGList = function (string) {
121 string = string.trim();
122
123 // 创建单原子广义表
124 var q;
125 if (isWord(string)) {
126 this.tag = ATOM;
127 this.atom = string;
128 } else {
129 this.tag = LIST;
130 var p = this;
131
132 // 脱外层括号
133 var sub = string.substr(1, string.length - 2);
134
135 do {
136 var hsub;
137 var n = sub.length;
138 var i = 0;
139 var k = 0;
140 var ch;
141
142 do {
143 ch = sub[i++];
144 if (ch == ‘(‘) ++k;
145 else if (ch == ‘)‘) --k;
146 } while (i < n && (ch != ‘,‘ || k != 0));
147
148 // i为第一个逗号分隔索引
149 if (i < n) {
150 hsub = sub.substr(0, i - 1);
151 sub = sub.substr(i, n - i);
152
153 // 最后一组
154 } else {
155 hsub = sub;
156 sub = ‘‘;
157 }
158
159 if(hsub === ‘()‘)
160 p.ptr.hp = null;
161 else
162 // 创建表头结点
163 this.createGList.call((p.ptr.hp = new GLNode()), hsub);
164
165 q = p;
166
167 // 创建表尾结点
168 if (sub) {
169 p = new GLNode();
170 p.tag = LIST;
171 q.ptr.tp = p;
172 }
173 } while (sub);
174
175 q.ptr.tp = null;
176 }
177 };
178
179 var node = new GLNode();
180 node.createGList(‘((), (ea), (sa, (bd, ce, dh)))‘);
181 console.log(node.depth());
182
183 GLNode.equal = function equal(gList1, gList2) {
184 // 空表时相等的
185 if (!gList1 && !gList2) return true;
186 if (gList1.tag === ATOM && gList2.tag === ATOM && gList1.atom === gList2.atom) return true;
187
188 if (gList1.tag === LIST && gList2.tag === LIST) {
189 // 表头表尾都相等
190 if (equal(gList1.ptr.hp, gList2.ptr.hp) && equal(gList1.ptr.tp, gList2.ptr.tp)) return true;
191 }
192
193 return false;
194 };
195
196 // 递归逆转广义表
197 GLNode.prototype.reverse = function reverse() {
198 var ptr = [];
199 // 当A不为原子且表尾非空时才需逆转
200 if (this.tag === LIST && this.ptr.tp) {
201 for (var i = 0, p = this; p; p = p.ptr.tp, i++) {
202 // 逆转各子表
203 if (p.ptr.hp) reverse.call(p.ptr.hp);
204
205 ptr[i] = p.ptr.hp;
206 }
207
208 // 重新按逆序排列各子表的顺序
209 for (p = this; p; p = p.ptr.tp)
210 p.ptr.hp = ptr[--i];
211 }
212 };
213
214 var global = Function(‘return this‘)();
215 GLNode.prototype.toString = function () {
216 var str = ‘‘;
217 if (this == global) str = ‘()‘;
218 else if (this.tag === ATOM) str = this.atom; // 原子
219 else {
220 str += ‘(‘;
221
222 for (var p = this; p; p = p.ptr.tp) {
223 str += this.toString.call(p.ptr.hp);
224 if (p.ptr.tp) str += ‘, ‘;
225 }
226 str += ‘)‘;
227 }
228
229 return str;
230 };
231
232 // 按层序输出广义表
233 // 层序遍历的问题,一般都是借助队列来完成的,每次从队头
234 // 取出一个元素的同时把它下一层的孩子插入队尾,这是层序遍历的基本思想
235 GLNode.prototype.orderPrint = function(){
236 var queue = [];
237 for(var p = this; p; p = p.ptr.tp) queue.push(p);
238
239 while(queue.length){
240 var r = queue.shift();
241 if(r.tag === ATOM) console.log(r.atom);
242 else {
243 for(r = r.ptr.hp; r; r = r.ptr.tp)
244 queue.push(r);
245 }
246 }
247 };
248
249 // 使用链队列
250 var Queue = require(‘../Queue/Queue.js‘).Queue;
251 GLNode.prototype.orderPrint2 = function(){
252 var queue = new Queue();
253
254 for(var p = this; p; p = p.ptr.tp) queue.enQueue(p);
255
256 while(queue.size){
257 var r = queue.deQueue();
258 if(r.tag === ATOM) console.log(r.atom);
259 else {
260 for(r = r.ptr.hp; r; r = r.ptr.tp)
261 queue.enQueue(r);
262 }
263 }
264 };
265
266 console.log(node + ‘‘);
267 node.reverse();
268 console.log(node + ‘‘);
269
270 var node2 = new GLNode();
271 node.copyList(node2);
272 console.log(GLNode.equal(node, node2));
273
274 console.log(node + ‘‘);
275 console.time(‘A‘);
276 node.orderPrint();
277 console.timeEnd(‘A‘);
278
279 console.log(‘------------------------------------‘);
280 console.time(‘B‘);
281 node.orderPrint2();
282 console.timeEnd(‘B‘);
283
284 /*
285 m元多项式表示
286
287 如果用线性表来表示,则每个数据元素需要m+1个数据项,以存储一个系数和m个指数值,这将产生两个问题。
288 一是无论多项式中各项的变元数是多是少,若都按m个变元分配存储空间,则将造成浪费;反之,若按各项实际的变元数分配存储空间,就会造成结点的大小不匀,给操作带来不便。二是对m值不同的多项式,线性表中的结点大小也不同,这同样引起存储管理的不便。
289 故不适于用线性表表示。
290
291 例如三元多项式:
292 P(x, y, z) = x(10)y(3)z(2) + 2x(6)y(3)z(2) + 3x(5)y(2)z(2) + x(4)y(4)z + 2yz + 15
293
294 如若改写为:
295 P(x, y, z) = ((x(10) + 2x(6))y(3) + 3x(5)y(2))z(2) + ((x(4) + 6x(3))y(4) + 2y)z + 15
296
297 用广义表表示:
298 P = z((A, 2), (B, 1), (15, 0))
299 A = y((C, 3), (D, 2))
300 B = y((E, 4), (F, 1))
301 C = x((1, 10), (2, 6))
302 D = x((3, 5))
303 E = x((1, 4), (6, 3))
304 F = x((2, 0))
305
306
307 */
308
309 function MPNode() {
310 // 区分原子结点和表结点
311 this.tag = undefined;
312 // 指数域
313 this.exp = 0;
314
315 // 系数域
316 this.coef = 0;
317 // 表结点的表头指针
318 this.hp = null;
319
320 // 相当于线性表的next,指向下一个元素结点
321 this.tp = null;
322 }

javascript实现数据结构:广义表,布布扣,bubuko.com

时间: 2024-12-23 05:53:19

javascript实现数据结构:广义表的相关文章

数据结构——广义表

定义 Python中的list就是一种广义表,使用起来非常方便.广义表的特点就是能够存储不同类型的元素,也支持嵌套使用,即表中还有表.关于广义表的定义还有几本操作归纳如下: ADT Linear List: 元素组成: 能存储不同元素类型的表结构叫做广义表,支持嵌套操作. 基本操作: InitGList() 创建一个空表 DestoryGList() 销毁一个表 GListLength()  获取表的长度 GListDepth()  获取表的深度 PrintList() 遍历一次表 Insert

数据结构 - 广义表

广义表 什么是广义表呢? (1)广义表是由零个或多个原子或子表组成的有限序列,是线性表的推广 (2) 广义表一般记作:LS=(d1,d2,-,dn) (3)di可以是单个元素,也可以是广义表,分别称为广义表LS的原子和子表 广义表概念 (1)当广义表LS非空时,称第一个元素d1为LS的表头(Head),称其余元素组成的子表(d2,-,dn)是LS的表尾(Tail) (2)非空广义表可唯一分解成表头和表尾:反过来,由表头和表尾可唯一组成一个广义表 (3)广义表括号的层数定义为广义表的深度 广义表特

数据结构广义表实验

一.问题描述: 1.题目内容:识别广义表的“头”或“尾”的演示 写一个程序,建立广义表的存储结构,演示在此存储结构上实现的广义表求头/求尾操作序列的结果. 2.基本要求 (1)设一个广义表允许分多行输入,其中可以任意地输入空格符,原子是不限长的仅字母或数字组成的串. (2)广义表采用如教材中结点的存储结构,试按表头和表尾的分解方法编写建立广义表存储结构的算法. (3)对已建立存储结构的广义表施行操作,操作序列为一个仅由“t“或”h”组成的串,它可以是空串(此时印出整个广义表),自左至右施行各操作

C++ 数据结构 广义表

GeneralList-广义表 广义表是非线性的结构,是线性表的一种扩展,是有n个元素组成有限序列. 广义表的定义是递归的,因为在表的描述中又得到了表,允许表中有表. <1> A = () <2> B = (a,b) <3> C = (a,b,(c,d)) <4> D = (a,b,(c,d),(e,(f),h)) <5> E = (((),())) #define _CRT_SECURE_NO_WARNINGS 1 #define _CRT_S

广义表的表示javascript

广义表是线性表的推广,也有人称其为列表. 那么它和线性表有什么区别呢?线性表中每个成员只能是单个元素,而广义表中的成员可以是单个元素,也可以是广义表,分别称为广义表的原子和子表.下面举几个广义表的例子. A=(); B=(e); C=(a,(b,c,d)); D=((),(e),(a,(b,c,d))); E=(a,E); 由于广义表中的数据元素可以具有不同的结构(原子或列表),因此难以用顺序存储结构表示,通常采用链式存储结构.由于列表中的元素可以是原子也可以是列表,所以需要两种结构的节点,一种

数据结构实践项目——数组和广义表

本文针对 [数据结构基础系列网络课程(5):数组和广义表] 1. 数组的基本概念与存储结构 2. 特殊矩阵的压缩存储 3. 稀疏矩阵的三元组表示 4. 稀疏矩阵的十字链表表示 5. 广义表 6. 广义表的存储结构及基本运算的实现 [项目1 - 猴子选大王(数组版)] 一群猴子,编号是1,2,3 -m,这群猴子(m个)按照1-m的顺序围坐一圈.从第1只开始数,每数到第n个,该猴子就要离开此圈,这样依次下来,最后一只出圈的猴子为大王.输入m和n,输出猴子离开圈子的顺序,从中也可以看出最后为大王是几号

数据结构与算法系列研究四——数组和广义表

稀疏矩阵的十字链表实现和转置 一.数组和广义表的定义 数组的定义1:一个 N 维数组是受 N 组线性关系约束的线性表.           二维数组的逻辑结构可形式地描述为:           2_ARRAY(D,R)              其中 D={aij} | i=0,1,...,b1-1; j=0,1,...,b2-1;aij∈D0}              R={Row,Col}              Row={<aij,ai,j+1>|0<=i<=b1-1;

33. 蛤蟆的数据结构笔记之三十三广义表实现二

33. 蛤蟆的数据结构笔记之三十三广义表实现二 本篇名言:" 希望是附丽于存在的,有存在,便有希望,有希望,便是光明.--鲁迅" 我们继续来看下广义表的其他代码实现.代码均来自网络,解释来自蛤蟆,均亲测可行. 欢迎转载,转载请标明出处: 1.  广义表实现二 1.1         main 创建两个链表的指针head和L. 输入一个字符串,调用GLCreate函数创建广义表.显示,获取头表,尾表,输出长度,深度,原子个数,复制列表,Merge列表,遍历,比较广义表操作. 如下图1:

数据结构算法C语言实现(十九)--- 5.5&amp;5.6&amp;5.7广义表

一.简述 传说Lisp的基本数据结构就是广义表,广义表也是具有典型递归属性的数据结构,此外,由于建表要处理字符串,用C语言处理起来也是一脸懵逼.....最后自己还想写一个将广义表还原成字符串的函数,一是使其可视化,而是验证算法5.6.花了不少功夫才写出来(强烈建议自己动手写一写),最后是借助树形结构的角度才找到一个不错的解决办法.按照<数据结构编程实验>的分类,数据结构无非线性结构.树状结构.图结构,可以说树是特殊的图(图的最小生成树),线性表示特殊的树.....扯远了! 二.头文件 补充版字