数据结构_数组与广义表_广义表的建立、遍历、复制、求深度
由一个存储着广义表信息的字符串建立一个广义表,并对其进行复制,求深度。
递归真是奇妙无穷啊,有些看似很复杂的东西只要找到规律就能进行递归求解。让我不得不对那些发现规律利用规律创造新事物的人肃然起敬。其实在众多美丽的事物中,人的思想也是很美丽的,那些数学家,哲学家能在意识的世界创造出瑰丽的奇观,让无数后人敬仰不已,好多人不理解数学家和哲学家,认为他们太古板太疯狂,其实他们是被物质世界蒙蔽了双眼,看到各种现实世界的不完美,每天纠结于菜价油价和七大姑八大姨的琐事之中。相反倒是那些他们不理解的数学家和哲学家活在自己创造出的“完美世界”,其乐无穷。美丽的思想,美丽的心灵。为那些数学家和哲学家致敬!
glists.h
#include<iostream>
#include<string>
using namespace std;
typedef enum
{
ATOM, LIST
} ElemTag;
typedef char AtomType;
typedef struct GLNode //GLNode是一个类型名
{
ElemTag tag; //标志域
union
{
AtomType atom;
struct
{
GLNode *hp, *tp;
} ptr;
//ptr是列表,hp,tp分别指向该列表的表头和表尾
};
GLNode()
{
ptr.hp = ptr.tp = NULL;
}
} *List; //List是指向GLNode类型变量的指针类型
class GLists
{
public:
void GetGList(List&); //得到广义表
void CopyGList(List&, List&); //复制广义表
void ListTraverse(List);
int GListDepth(List&); //求广义表深度
private:
void CreatGList(List&, string&); //递归建立广义表
void sever(string&, string&); //存储广义表的字符串处理
};
void GLists::GetGList(List &l)
{
cout << "Please Input The Lists :" << endl << endl;
string str;
cin >> str;
CreatGList(l, str);
}
void GLists::CreatGList(List &l, string &s) //根据给定字符串s,从l递归创建广义表
{
List p, q; //广义表节点类型变量
string sub, hsub; //两个字符串
if (s == "()") //空表
l = NULL; //l置空
else //非空表
{
l = new GLNode; //建立节点
if (s.size() == 1) //原子类型
{
l->tag = ATOM; //标志域
l->atom = s[0]; //原子
} //if
else //列表类型
{
l->tag = LIST; //标志域
p = l;
sub = s.substr(1, s.size() - 2); //脱去括号
do //根据得到的列表字符串建立新的广义表
{
sever(sub, hsub); //得到列表中“最小单位”hsub,然后把sub置成去掉最小单位的剩余字符串
CreatGList(p->ptr.hp, hsub); //递归建立广义表
q = p; //记录p
if (!sub.empty()) //为下一个节点提前开辟节点空间
{
p = new GLNode;
p->tag = LIST; //更改标志域
q->ptr.tp = p; //连接节点
}
} while (!sub.empty());
}
} //else
}
void GLists::CopyGList(List &t, List &l) //复制广义表l->t
{
if (!l)
t = NULL; //l是空表
else
{
t = new GLNode; //开辟节点
t->tag = l->tag; //标志域
if (l->tag == ATOM) //是原子节点
t->atom = l->atom; //复制原子
else //列表
{
CopyGList(t->ptr.hp, l->ptr.hp); //递归复制表头
CopyGList(t->ptr.tp, l->ptr.tp); //递归复制表尾
}
}
}
int GLists::GListDepth(List &l) //求广义表深度
{
int max = 0, dep;
List p = l;
if (l == NULL)
return 1; //空表深度为1
if (l->tag == ATOM)
return 0; //原子深度为零
//非空列表情况
for (; p; p = p->ptr.tp) //遍历列表
{
dep = GListDepth(p->ptr.hp); //递归求深度
if (dep > max) //更新max
max = dep;
}
return max + 1; //返回深度
}
void GLists::sever(string &str, string &hstr) //广义表字符串处理
{ //将非空字符串分割成两部分hstr为第一个','之前的部分,str为之后的部分
int n = str.size(), i = 0, k = 0;
do
{
if (str[i] == '(')
k++;
if (str[i] == ')')
k--;
i++;
} while (i < n && (str[i] != ',' || k != 0));
if (i < n)
{
hstr = str.substr(0, i);
str = str.substr(i + 1, n - i - 1);
}
else
{
hstr = str;
str.clear();
}
}
void GLists::ListTraverse(List L) //广义表遍历
{
if (L->tag == ATOM)
{
cout << L->atom << ",";
}
else
{
cout << "(";
while (L != NULL)
{
ListTraverse(L->ptr.hp);
L = L->ptr.tp;
}
cout << ")";
}
}
main.cpp
#include"glists.h"
int main()
{
GLists gl;
List l,t;
gl.GetGList(l);
gl.CopyGList(t,l);
cout<<gl.GListDepth(l)<<endl;
cout<<gl.GListDepth(t)<<endl;
gl.ListTraverse(l);//遍历广义表
system("pause");
}