实现方法如下:
(1)从左到右扫描树的括号表示;
(2)每当遇到左括号时,其前一个结点进栈,并读入下一个符号;
(3)每当遇到右括号时,栈顶元素出栈。说明以栈顶元素为根的树(子树)构造完毕,此时若栈为空,算法结束,否则读入下一个符号
(4)每当遇到结点时,则它一定为栈顶元素的子女,将其挂到栈顶元素的某子女位置上,并读入下一个符号;
(5)每当遇到“,”,则略过该符号,并读入下一个符号。
如图所示:
完整代码如下:
/* 二叉树 - 根据嵌套括号表示法的字符串生成链式存储的二叉树 */
#include <iostream>
#include <malloc.h>
using namespace std;
const int MaxSize = 50;
typedef char ElementType; //typedef用来给数据类型char起别名(ElementType)
typedef struct bitnode
{
ElementType data;
struct bitnode *left, *right;
} bitnode, *bitree; //bitree为指向bitnode这种自定义数据的指针
//函数声明
void CreateTree(bitree &b, char str[]); //根据嵌套括号表示法的字符串生成链式存储的二叉树
void PrinTree(bitree b); //以嵌套括号表示法输出一棵树
bitree FreeTree(bitree b); //释放空间
//根据嵌套括号表示法的字符串生成链式存储的二叉树
void CreateTree(bitree &b, char str[])
{
char ch;
bitree stack[MaxSize],p; //stack[MaxSize]为指针数组,其每一个元素都为指向bitnode这种结构的指针,p为临时指针
int top = -1, k, j = 0; //top为栈顶指针、k决定谁是左、右孩子、j为str指针
while( (ch = str[j++]) != '\0' )
{
switch(ch)
{
case '(':
top++;
stack[top] = p; //根节点入栈
k = 1; //1为左孩子
break;
case ',':
k = 2; //2为右孩子
break;
case ')':
top--; //根节点出栈
break;
default:
p = (bitree)malloc(sizeof(bitnode));
p->data = ch;
p->left = p->right = NULL;
if( b == NULL ) //树为空时
b = p;
else //树非空时
{
switch(k)
{
case 1:
stack[top]->left = p; //根节点的左孩子
break;
case 2:
stack[top]->right = p; //根节点的右孩子
break;
}
}
}
}
}
//以嵌套括号表示法输出一棵二叉树
void PrinTree(bitree b)
{
if( b )
{
cout << b->data; //访问根节点
if( b->left != NULL || b->right != NULL )
{
cout << "(";
PrinTree(b->left); //递归处理左子树
if(b->right != NULL)
cout << ",";
PrinTree(b->right); //递归处理右子树
cout << ")";
}
}
}
bitree FreeTree(bitree b)
{
if( b != NULL )
{
FreeTree(b->left); //递归释放左子树
FreeTree(b->right); //递归释放右子树
free(b); //释放根节点
b = NULL; //释放指向根节点的指针
}
return b; //return NULL;
}
int main()
{
char str[] = "a(b(c),d(e(,f),g))";
bitree root = NULL; //不要忘记初始化
CreateTree(root,str);
cout << "str字符串:" << str << endl;
cout << "嵌套表示法:";
PrinTree(root);
cout << endl;
root = FreeTree(root);
if( root == NULL )
cout << "释放成功" << endl;
return 0;
}
运行结果如下:
后记:
最近在看一本书,是红衣教主周鸿祎写的《我的互联网方法论》,他讲到了互联网的本质——Free,没错,就是免费,Internet这条信息高速公路不仅仅需要哪些专业人士去建造,而且需要我们每一个人来贡献出一些东西,我们需要站在巨人的肩膀上去眺望未来,编程也是这样,不要刀耕火种,我们需要交流,相互交流,这也是我为什么要花我的一部分时间来写博客的原因,我所写的这些东西也许都是上个世纪的产物了,很多人都在写,但是我希望我们每个人都来写,因为分享知识从来都是一件令人快乐的事。