核心思想:
1.节点类中用一个标志域区别是表还是元素
2.节点类中使用联合体
3.广义表类中存放一个起始指针
广义表类中的操作函数:
1.创建
1.两个函数的形式,详见代码注释
2.两次接受输入,方便递归,见注释
3.通过递归时传参传tlink ,hlink指针(由于要修改指针,传的引用),后面函数直接用他们创造结点,巧妙避开结点连接问题
4.输入格式:空表用#表示,每个之间加逗号,用分号表示结束
例如:a,(#),b,c,(d,(e));
(如果觉得对输入要求过高,可以使用一个字符串保存输入,然后加一个处理函数,把其他格式的输入转化为此输入,函数中读输入时从该字符串中读即可)
2.遍历(以按格式输出得到形式)
1 两个函数的形式
3.复制
1 两个函数
第一个函数返回一个复制好的对象,第二个函数进行递归复制
(第二个函数也可以将被复制的广义表按格式输出到字符串中,然后通过读取该字符串来创建一个新的广义表以达到复制目的)
2.递归复制与创建类似,只不过是分配新的内存时,用被复制的广义表来初始化
4.查找给定值
1.两个函数,因为主函数里不一定有first指针,且第二个函数要引入一个标志变量
2.引入一个标志变量tag(初始化为0,因为要改变他的值,所以是引用),如果遍历过程中找到了,将tag置1
3.布尔类型的返回值判断是否找到
5.输出广义表及其层次
1多加一个变量 i 表示他的层次,如果进入了下一层次,i+1
2.同样需要两个函数
3.层次从1开始,每进一次子表层次加1
#include<bits/stdc++.h>
using namespace std;
class node
{
int flag;//用来区别是原子还是表
union
{
char data;//为原子时存放数据
node* hlink;//为表时存放下一个表的指针
};//联合体,其中的元素只能存在一个
node* tlink;
public:
friend class glist;
};
class glist
{
node* first;
public:
glist()
{
first = NULL;
}
//创建广义表
void creat_glist()
{
creat_glist(first);
}//设置两个函数是因为主函数中不一定有first指针,第二个函数带指针参数是为了递归
void creat_glist(node*& gs)
{
char a;
cin >> a;
if (a == '#')
{
gs = NULL;
}//如果不加表示空表的符号话,当空表时,读入')'的时候会进入else分支
else if (a == '(')
{
gs = new node;
gs->flag = 1;
creat_glist(gs->hlink);
}
else
{
gs = new node;
gs->flag = 0;
gs->data = a;
}
cin >> a;//再加一个输入是为了递归回来后能进行后续的读入
if (gs == NULL);
else if (a == ',')
{
creat_glist(gs->tlink);
}
else if ((a == ')') || (a == ';'))
{
gs->tlink = NULL;
}
}
//遍历(按格式输出)广义表
void traverse()
{
cout << endl << "there are the list:" << endl;
traverse(first);
cout << ";" << endl;
}
void traverse(node* gs)
{
if (gs->flag == 1)
{
cout << "(";//输出表示表的左括号
if (gs->hlink == NULL)
{
cout << "#";
}
else
{
traverse(gs->hlink);
}
cout << ")";//递归回来后补上一个右边括号
}
else
{
cout << gs->data;
}
if (gs->tlink != NULL)
{
cout << ",";//逗号的输出与否看后续还有没有结点
traverse(gs->tlink);
}
}
//复制广义表
glist copy_glist()
{
glist b;
copy_glist(b.first, first);
return b;
}
void copy_glist(node*& gs, node* gs_final)
{
if (gs_final->flag == 1)
{
gs = new node;
gs->flag = 1;
if (gs_final->hlink == NULL)
gs->hlink = NULL;
else
copy_glist(gs->hlink, gs_final->hlink);
}
else
{
gs = new node;
gs->flag = 0;
gs->data = gs_final->data;
}
if (gs_final->tlink == NULL)
gs->tlink = NULL;
else
{
copy_glist(gs->tlink, gs_final->tlink);
}
}
//查找给定值
bool find_in_glist(char a)
{
int b = 0;
return find_in_glist(first, a, b);
}
bool find_in_glist(node* gs, char a, int& tag)
{
if (gs->flag == 1)//因为下面要用else,所以这里不宜用(gs->flag == 1)&&(gs->hlink!=NULL)
{
if (gs->hlink != NULL)
find_in_glist(gs->hlink, a, tag);
}
else
{
if (gs->data == a)
tag = 1;
}
if (gs->tlink != NULL)
find_in_glist(gs->tlink, a, tag);
return tag == 1;
}
//输出广义表元素以及其层次
void show_glist_and_its_level()
{
int a = 1;
show_glist_and_its_level(first, a);
}
void show_glist_and_its_level(node* gs, int i)
{
if (gs->flag == 1)
{
if (gs->hlink != NULL)
show_glist_and_its_level(gs->hlink, i + 1);
}
else
{
cout << gs->data << " " << i << endl;
}
if (gs->tlink != NULL)
show_glist_and_its_level(gs->tlink, i);
}
};
int main()
{
glist a;
a.creat_glist();
a.traverse();
char d;
a.show_glist_and_its_level();
while (1)
{
cin >> d;
if (a.find_in_glist(d))
{
cout << "succeed" << endl;
}
else
{
cout << "not find it" << endl;
}
}
glist b;
b = a.copy_glist();
b.traverse();
}
//a,(#),b,c,(d,(e));
参考:数据结构(c++版)(第二版)清华大学出版社 陈宝平等主编