2.广义表

2.广义表

明廷盛 嘻嘻😁

第一章 自测&关键词回顾

广义表概念: 青岛大学-数据结构
广义表实现: link
C语言基础联合体: 视频

第二章 手撕

①其实还有一种用类似”树形”的实现方式, 原理差不多; ②我实现的比较偏应试,没有具体操作广义表的节点的函数实现

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>

#define MAX(a, b) ((a) > (b) ? (a) : (b))

typedef char DataType;

typedef struct GeneralListNode {
int tag; // 1表示字表节点; 0表示元素节点
union {
DataType data;
struct GeneralListNode *subList;
};
struct GeneralListNode *next;
} GeneralListNode;

// 初始化
void initGeneralList(GeneralListNode **glist);
// 遍历
void traverseGeneralList(GeneralListNode *glist);

// 获取广义表长度(元素个数)
int getLength(GeneralListNode *glist);
// 获取广义表的深度
int getDepth(GeneralListNode *glist);
// 获取广义表的表头
GeneralListNode *getHead(GeneralListNode *glist);
// 获取广义表的表尾
GeneralListNode *getTail(GeneralListNode *glist);
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
#include "generalList.h"

// 初始化
void initGeneralList(GeneralListNode **glist) {
char input;
scanf("%c", &input);
if (input == '(') { // 说明是一个表节点
GeneralListNode *newNode = (GeneralListNode *)malloc(sizeof(GeneralListNode));
newNode->tag = 1;
// TODO
initGeneralList(&(newNode->subList));
initGeneralList(&(newNode->next));
*glist = newNode;
} else if (input == ',') {
initGeneralList(glist);
} else if (input == ')' || input == '\n') {
*glist = NULL;
} else { // 是元素(原子)
GeneralListNode *newNode = (GeneralListNode *)malloc(sizeof(GeneralListNode));
newNode->tag = 0;
newNode->data = input;
initGeneralList(&(newNode->next));
*glist = newNode;
}
}
// 遍历
void traverseGeneralList(GeneralListNode *glist) {
if (glist == NULL) {
printf("不存在该表");
return;
}
if (glist->tag == 1) {
printf("(");
traverseGeneralList(glist->subList);
printf(")");
} else {
if (glist->data == '#')
printf("");
else
printf("%c", glist->data);
}

if (glist->next != NULL) {
printf(",");
traverseGeneralList(glist->next);
}
}

// 获取广义表长度(元素个数)
int getLength(GeneralListNode *glist) {
int len = 0;
GeneralListNode *ghead = glist->subList;
// 空表
if (ghead->tag == 0 && ghead->data == '#')
return len;
// 长度至少为1 or 至少有一个元素
else {
while (ghead) {
len++;
ghead = ghead->next;
}
return len;
}
}

/**
* 获取广义表的深度
* 广义表深度的定义: 空表的深度为1, 原子(元素)的深度为0
* 考试就 数左括号, 数到第一个右括号为止
*/
int getDepth(GeneralListNode *glist) {
if (glist->tag == 0 && glist->next == NULL)
return 0;
else {
int p1 = glist->next != NULL ? getDepth(glist->next) : 0;
// 只有tag为1才有子表; 不能判断这个glist->subList != NULL, 有坑哈
int p2 = glist->tag == 1 ? getDepth(glist->subList) : 0;
return glist->tag + MAX(p1, p2); // 只有表才会多送1层; 节点是不能送1层(否则会凭空多一层)
}
}
// 获取广义表的表头
GeneralListNode *getHead(GeneralListNode *glist) {
GeneralListNode *ghead = glist->subList;
// 空广义表,没有表头
if (ghead->tag == 0 && ghead->data == '#')
return NULL;
GeneralListNode *resGHead = (GeneralListNode *)malloc(sizeof(GeneralListNode));
resGHead->tag = ghead->tag;
resGHead->next = NULL;
if (resGHead->tag)
resGHead->subList = ghead->subList;
else
resGHead->data = ghead->data;
return resGHead;
}
// 获取广义表的表尾
GeneralListNode *getTail(GeneralListNode *glist) {
GeneralListNode *ghead = glist->subList;
// 空广义表,没有表头
if (ghead->tag == 0 && ghead->data == '#')
return NULL;

// 表尾一定是一个表
GeneralListNode *newGList = (GeneralListNode *)malloc(sizeof(GeneralListNode));
newGList->tag = 1;
newGList->next = NULL;

GeneralListNode *tailGList = ghead->next; // 假"表尾"
// 说明是表尾是一个空表
if (tailGList == NULL) {
tailGList = (GeneralListNode *)malloc(sizeof(GeneralListNode));
tailGList->tag = 0;
tailGList->data = '#'; // #表示空表
tailGList->next = NULL;
}
newGList->subList = tailGList; // 封装为一个表
return newGList;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
#include "generalList.h"

void test01(void) {
// A = (a,(b,c),y)
// B = (((a,b,(#),c),d),e,((f),g))
GeneralListNode *glist = (GeneralListNode *)malloc(sizeof(GeneralListNode));
initGeneralList(&glist);

traverseGeneralList(glist);
printf("\n");
printf("Length: %d\n", getLength(glist));
printf("Depth: %d\n", getDepth(glist));
GeneralListNode *ghead = getHead(glist);

printf("Head: ");
if (ghead == NULL) // 不存在
printf("不存在");
else if (ghead->tag == 0) // 是一个元素(原子)
printf("%c", ghead->data);
else // 是一个字表
traverseGeneralList(ghead);

printf("\n");

GeneralListNode *gtail = getTail(glist);
printf("Tail: ");
if (gtail == NULL) // 不存在
printf("不存在");
else
traverseGeneralList(gtail);
printf("\n");
}

void linkModifyTest() {
GeneralListNode *glist = (GeneralListNode *)malloc(sizeof(GeneralListNode));
initGeneralList(&glist); // (((a,b,(#),c),d),e,((f),g))
traverseGeneralList(glist);
puts("");

// ((a,b,(#),c),d)
// (a,b,(#),c)
// (b,(#),c)
// ((#),c)
// ()
// GeneralListNode* ans = getTail(getTail(getHead(getHead(glist))));
// 不存在该表
GeneralListNode* ans = getHead(getHead(getTail(getTail(getHead(getHead(glist))))));
traverseGeneralList(ans);
}

int main() {
// test01();
linkModifyTest();
return 0;
}

第三章 相关应用

第四章 上手真题

第五章 比赛怎么用

  • Title: 2.广义表
  • Author: 明廷盛
  • Created at : 2025-03-17 11:22:33
  • Updated at : 2025-03-24 00:07:00
  • Link: https://blog.20040424.xyz/2025/03/17/🏫考研/第一部分 数据结构/2.广义表/
  • License: All Rights Reserved © 明廷盛