二叉树的括号法建立与遍历(C/C++)

括号法表示二叉树,如下例:

A(B(#,D),C(E(#,F),#))

字母代表结点,字母后面的括号为该结点的子树,逗号左边为左子树,逗号右边为右子树。

建立:

观察括号法的表达式可知,处理完一个结点后,紧接着是继续处理其子结点,处理完其子结点,又要继续处理其子结点的子结点,即后来的先处理,是一种后进先出的思想,所以这里将借助栈结构完成此算法。
观察括号法的表达式易知,输入的字符有以下几类:①正常字符(如字母):用户要保存到结点中的值;②左括号:其右边跟着的是其左边那个结点的子树;③逗号:其右边是其左边那个结点的兄弟结点;④右括号:表示左边那个结点不再有子树,且其父结点也不再有子树;⑤井号:表示无效字符,将指针值设为nullptr。
首先获取栈顶结点,然后获取输入的字符,不同的字符做不同的处理。如果是左括号,代表当前结点有左子树,则左子树申请一块内存,并将左子树地址压入栈中;如果是逗号,说明当前结点有右子树,则申请内存并压入栈;如果是右括号,说明当前结点处理完毕,将其及其右子树都弹出栈;如果是井号,则删除当前结点并出栈,此时的新栈顶便是其父结点,要将父结点的左子树或右子树设置为nullptr;如果是正常字符,保存到当前结点中即可。重复这个过程,直到栈空。

void BracketsCreatBiTree(BiTree *&T)
{
	stack<BiTree*> S;
	//先处理根结点
	char ch;
	cin >> ch;
	if (ch == '#')
	{
		T = nullptr;
		return;
	}
	T = new BiTree;
	T->data = ch;
	S.push(T);
	BiTree *p=T;
	//循环处理子树
	while (!S.empty())
	{
		p = S.top();
		cin >> ch;
		if (ch == '(')//表示当前结点拥有子树
		{
			p->lchild = new BiTree;
			S.push(p->lchild);
		}
		else if (ch == ',')//表示当前结点拥有右子树
		{
			p->rchild = new BiTree;
			S.push(p->rchild);
		}
		else if (ch == ')')//表示一个结点的左右子树处理完毕,将其及其右子树出栈
		{
			S.pop();
			S.pop();
		}
		else if (ch == '#')//表示当前结点为空
		{
			delete p;
			S.pop();
			p = S.top();
			if (p->rchild == nullptr) p->lchild = nullptr;
			else p->rchild = nullptr;
		}
		else//表示当前获取到的字符为要保存的值
		{
			p->data = ch;
		}
	}
}
遍历:

先输出根结点,若不存在就输出“#”;
如果有子树存在,先输出左括号,然后判断左子树是否存在,存在则递归,不存在则输出“#”;
再输出逗号,如果右子树存在,递归右子树,否则输出“#”,最后输出右括号。

void BracketsTravers(BiTree *&T)
{
    cout << T->data;
    if(T->lchild!=nullptr || T->rchild!=nullptr)//若存在子树
    {
        cout << "(";
        if(T->lchild!=nullptr) BracketsTravers(T->lchild);//若存在左子树
        else cout << "#";
        cout << ",";
        if(T->rchild!=nullptr) BracketsTravers(T->rchild);//若存在右子树
        else cout << "#";
        cout << ")";
    }
}
  • 1
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值