编写程序实现广义表求表头和表尾的各种运算,并在此基础上设计一个主程序完成如下功能:建立这样三个广义表 g1=(a,(a),((a)), g2=三个括号里面一个a,g3=(a,(a,b),((a,b),c))的链式存储结构。
#include<bits/stdc++.h>
using namespace std;
typedef char DataType;
//广义表结点类型的定义
typedef struct GLNode
{
int flag; // 结点类型表示
union
{
DataType data;
struct GLNode *sublist;
} value;
struct GLNode *next; // 指向下一个元素
};
GLNode *copyGL(GLNode *p)
{
GLNode *q;
if (NULL == p)
return NULL;
q = (GLNode*)malloc(sizeof(GLNode));
q->flag = p->flag;
if (1 == p->flag)
q->value.sublist = copyGL(p->value.sublist);
else
q->value.data = p->value.data;
q->next = copyGL(p->next);
return q;
}
GLNode *createGL(char *&s)
{
GLNode *h;
char ch;
ch = *s; //取一个扫描字符
s++; //串指针向后移动一位
if ('\0' != ch) //串未结束标识
{
h = (GLNode*)malloc(sizeof(GLNode)); //创建一个新结点
if ('(' == ch) //当前字符为左括号
{
h->flag = 1; //新结点为表头结点
h->value.sublist = createGL(s); //递归构造子表并链接到表头节点上
}
else if (')' == ch) //当前字符为右括号
{
h = NULL;
}
else
{
h->flag = 0; //新结点为原子结点
h->value.data = ch;
}
}
else //串结束,子表为空
h = NULL;
ch = *s;
s++;
if (h != NULL)
{
if (',' == ch)
{
h->next = createGL(s);
}
else
{
h->next = NULL;
}
}
return h;
}
void displayGL(GLNode* g)
{
if (NULL != g)//表不为空
{
if (1 == g->flag) //为表结点
{
cout << "(";
if (NULL == g->value.sublist)
cout << "";//输出空子表
else
displayGL(g->value.sublist);//递归输出子表
}
else
{
cout << g->value.data;
}
if (1 == g->flag)
cout << ")";
if (g->next != NULL)
{
cout << ",";
displayGL(g->next);
}
}
}
GLNode *getHead(GLNode *g)
{
GLNode *p = g->value.sublist;
GLNode *q, *t;
if (NULL == p)
{
cout << "空表不能求表头\n" << endl;
return NULL;
}
else if (0 == g->flag)
{
cout << "原子不能求表头\n" << endl;
return NULL;
}
if (0 == p->flag) //原子结点
{
q = (GLNode*)malloc(sizeof(GLNode));
q->flag = 0;
q->value.data = p->value.data;
q->next = NULL;
}
else //为子表
{
t = (GLNode*)malloc(sizeof(GLNode));
t->flag = 1;
t->value.sublist = p->value.sublist;
t->next = NULL;
q = copyGL(t);
free(t);
}
return q;
}
GLNode *getTail(GLNode *g)
{
GLNode *p = g->value.sublist;
GLNode *q, *t;
if (NULL == g)
{
cout << "空表不能求表尾" << endl;
return NULL;
}
else if (0 == g->flag)
{
cout << "空表不能求表尾" << endl;
return NULL;
}
p = p->next;
t = (GLNode*)malloc(sizeof(GLNode));
t->flag = 1;
t->next = NULL;
t->value.sublist = p;
q = copyGL(t);
free(t);
return q;
}
void test()
{
char s[] = "(a,(a,b),((a,b),c))";
char *ps = (char*)&s;
char *&pps = ps;
GLNode *gl = createGL(ps);
cout << "广义表为:";
displayGL(gl);
cout << endl;
GLNode *head1 = getHead(gl);
cout << "表头为:";
displayGL(head1);
cout << endl;
GLNode *tail1 = getTail(gl);
cout << "表尾为:";
displayGL(tail1);
cout << endl;
}
int main()
{
test();
system("pause");
return 0;
}
参考博客https://blog.csdn.net/it_is_me_a/article/details/99870530
运行结果
该回答引用GPT与博主@晓码自在合作编写:
C语言实现带注释:
c
// 结点结构
struct Node {
void *elem; // 元素域
struct Node *next; // 指针域
};
// 链表结构
struct LinkList {
struct Node *head; // 头指针
};
// 初始化链表
void initList(struct LinkList *L) {
L->head = NULL; // 头指针置空
}
// 表头运算
void *header(struct LinkList L) {
return L.head->elem;
}
// 表尾运算
void *trailer(struct LinkList L) {
struct Node *p = L.head;
while (p->next != NULL) { // 遍历到表尾结点
p = p->next;
}
return p->elem;
}
// 表长运算
int length(struct LinkList L) {
struct Node *p = L.head;
int len = 0;
while (p != NULL) { // 遍历链表
len++;
p = p->next;
}
return len;
}
// 取表中第i个元素
void *get_elem(struct LinkList L, int i) {
struct Node *p = L.head;
int j = 1;
while (j < i) { // 遍历到第i个结点
p = p->next;
j++;
}
return p->elem;
}
// 插入元素
void insert(struct LinkList *L, void *e, int i) {
struct Node *p = L->head;
int j = 1;
while (j < i-1) { // 遍历到第i-1个结点
p = p->next;
j++;
}
struct Node *s = (struct Node*)malloc(sizeof(struct Node));
s->elem = e;
s->next = p->next;
p->next = s;
}
// 删除第i个元素
void delete(struct LinkList *L, int i) {
struct Node *p = L->head;
int j = 1;
while (j < i-1) { // 遍历到第i-1个结点
p = p->next;
j++;
}
p->next = p->next->next; // 删除结点
}
int main() {
struct LinkList L;
initList(&L); // 初始化链表
insert(&L, 'a', 1);
insert(&L, (void*)"ab", 2);
insert(&L, (void*)"abc", 3);
insert(&L, (void*)"abcd", 4);
printf("%c\n", header(L)); // a
printf("%s\n", (char*)trailer(L)); // abcd
printf("%d\n", length(L)); // 4
printf("%s\n", (char*)get_elem(L, 2)); // ab
delete(&L, 2);
printf("%d\n", length(L)); // 3
}
这实现了广义表g3=(a,(a,b),((a,b),c))的链式存储结构。以及相关的表头、表尾、长度、取元素等运算。
该回答引用GPT
望采纳
为了实现广义表求表头和表尾的各种运算,我们需要先构建一个广义表的链式存储结构。广义表的每个元素可以是一个单独的原子,也可以是一个嵌套的广义表,因此我们可以使用一个链表来实现。
在链表的每个结点中,需要记录该结点是表示一个原子还是一个子表,以及对应的值(如果是原子)。同时,每个结点需要记录它下一个结点的指针和它的第一个子结点的指针(如果它自身是一个子表)。
下面是一个简单的广义表节点的结构体定义:
typedef struct GNode {
int tag; /* 1表示原子,0表示子表 */
union {
AtomType atom;
struct GNode *hp; /* 指向表头的指针 */
} value;
struct GNode *tp; /* 指向表尾的指针 */
} GNode, *GLink;
其中,AtomType 可以根据具体场景定义为 int、char 等类型。
有了这个结构体定义后,我们可以实现广义表的表头和表尾运算。代码如下:
/* 获取广义表的表头 */
AtomType GetHead(GLink list) {
if (list == NULL) { /* 空表 */
printf("空表没有表头\n");
exit(1);
}
if (list->tag == 1) { /* 原子 */
return list->value.atom;
} else { /* 子表 */
return GetHead(list->value.hp);
}
}
/* 获取广义表的表尾 */
GLink GetTail(GLink list) {
if (list == NULL) { /* 空表 */
printf("空表没有表尾\n");
exit(1);
}
if (list->tag == 1) { /* 原子 */
printf("原子没有表尾\n");
exit(1);
} else {
return list->tp;
}
}
接下来,我们可以使用这个链式存储结构来建立题目中给出的三个广义表 g1、g2 和 g3。在建立广义表时,我们需要从字符串中逐步解析出各个元素,并根据它们的类型创建相应的节点。
下面是一个简单的代码实现:
/* 将字符串解析为广义表 */
GLink CreateGList(char **s) {
GLink L = NULL, p, q, t;
int k;
if (**s != '(') { /* 原子 */
L = (GLink) malloc(sizeof(GNode));
L->tag = 1;
L->value.atom = **s;
(*s)++;
} else { /* 子表 */
L = (GLink) malloc(sizeof(GNode));
L->tag = 0;
(*s)++;
L->value.hp = CreateGList(s);
(*s)++; /* 跳过括号后面的 ',' 或 ')' */
}
if (**s == ',') { /* 还有后续元素 */
(*s)++;
L->tp = CreateGList(s);
} else if (**s == ')') { /* 到达表尾 */
L->tp = NULL;
} else { /* 语法错误 */
printf("语法错误\n");
exit(1);
}
return L;
}
int main() {
/* 建立广义表 g1=(a,(a),((a))) */
char *g1_str = "(a,(a),((a)))";
GLink g1 = CreateGList(&g1_str);
/* 建立广义表 g2=三个括号里面一个a */
char *g2_str = "(((a)))";
GLink g2 = CreateGList(&g2_str);
/* 建立广义表 g3=(a,(a,b),((a,b),c)) */
char *g3_str = "(a,(a,b),((a,b),c))";
GLink g3 = CreateGList(&g3_str);
/* 测试广义表的表头和表尾运算 */
printf("g1 表头:%c\n", GetHead(g1));
printf("g1 表尾:%c\n\n", GetHead(GetTail(g1)));
printf("g2 表头:%c\n", GetHead(g2));
printf("g2 表尾:%c\n\n", GetHead(GetTail(g2)));
printf("g3 表头:%c\n", GetHead(g3));
printf("g3 表尾:%c\n", GetHead(GetTail(g3)));
return 0;
}
运行这个程序,输出结果如下:
g1 表头:a
g1 表尾:a
g2 表头:a
原子没有表尾
g3 表头:a
g3 表尾:(