广义表(C++)

核心思想:
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++版)(第二版)清华大学出版社 陈宝平等主编
  • 3
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值