输入广义表形式的树(字符串),删除指定值的节点(节点值为单个字母)及其子树,并且输出此时树的广义表形式

此博客介绍了如何从输入的广义表形式的树中删除指定值的节点及其子树,并输出更新后的树的广义表形式。通过先序遍历,建立树结构,然后使用栈辅助查找并删除目标节点及其子树。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

#include<iostream>
#include<string>
#include<stack>
using namespace std;
class Node{
public:
	char data;
	Node *lchild, *rchild;

	Node(char _data){
		data = _data;
		lchild = NULL;
		rchild = NULL;
	}
	~Node(){
		if (lchild != NULL){
			delete lchild;
			lchild = NULL;
		}
		if (rchild != NULL){
			delete rchild;
			rchild = NULL;
		}
	}
	void build(const string& str){//由广义表建树,其实就是先序遍历
		int k = -1;
		stack<Node*> Stack;
		Stack.push(this);
		for (int i = 1; i < str.length(); i++){
			if (str[i] == '('){
				k = 0;//表示进入下一层
				Node* p = new Node(str[i]);//标记节点,区分左右
				Stack.push(p);
			}
			else if (str[i] == ','){
				k = 1;//表示转向右子树
			}
			else if (str[i] == ')'){
				Stack.pop();//表示返回上一层
			}
			else {
				Node *temp = new Node(str[i]);
				if (k == -1){
					Stack.push(temp);//作为根节点直接入栈
				}
				else if (k == 0){//这种形式a,(b,c)
					if (Stack.top()->data == '('){
						Stack.pop();//也就把上次的左括号出栈
					}
					Stack.top()->lchild = temp;//作为栈顶的左孩子
					Stack.push(temp);
				}
				else if (k == 1){ //这种形式a(,c)
					Stack.pop();
					Stack.top()->rchild = temp;
					Stack.push(temp);
				}
			}
		}
	}
	void output(){//输出广义表形式
		cout << data;
		if (lchild != NULL){
			cout << '(';
			lchild->output();
		}
		if (rchild != NULL){
			if (lchild == NULL){
				cout << "(";
			}
			cout << ',';
			rchild->output();
			cout << ')';
		}
		if(lchild!=NULL&&rchild==NULL){//防止右子树为空时缺少右括号
			cout << ')';
		}
	}
};
class BinaryTree{
private:
	Node *root;
public:
	BinaryTree(){
		root = NULL;
	}
	BinaryTree(Node*& del){
		root = del;
	}
	BinaryTree(const string& str){//由广义表建树
		root = new Node(str[0]);
		root->build(str);
	}
	~BinaryTree(){
		if (root != NULL){
			delete root;
			root = NULL;
		}
	}
	void output(){
		root->output();
	}
	void find_remove(char delete_data){//查找值为delete_data的节点,并删除它及其子树。  前提:该值不能为 整棵树的根节点
		stack<Node*> s;
		s.push(root);
		Node* p = this->root;
		while (!s.empty()){
			/*
			栈的特点:先进后出
			先被访问的根节点的右子树后被访问
			*/
			if (p->lchild != NULL){ //找到父节点
				if (p->lchild->data == delete_data){
					BinaryTree deleteSubTree(p->lchild);//构建待删除的子树,利用析构函数删除
					deleteSubTree.~BinaryTree();
					p->lchild = NULL;  //切断子树
					return;
				}
			}
			if (p->rchild != NULL){
				if (p->rchild->data == delete_data){
					BinaryTree delete_tree(p->rchild);//构建待删除的子树,利用析构函数删除
					delete_tree.~BinaryTree();
					p->rchild = NULL;//切断子树
					return;
				}
			}

			if (p->rchild){
				s.push(p->rchild);
			}
			if (p->lchild){
				p = p->lchild;
			}
			else{
				//左子树访问完了,访问右子树  
				p = s.top();
				s.pop();
			}
		}
	}
};

int main(){
	string str;
	char search;
	cin >> str>>search;//7(4(3,6),1(,5))
	BinaryTree binarytree(str);
	if (str.find(search) == str.npos){//如果没找到这个数值
		binarytree.output();//直接输出
	}
	else{
		if (search != str[0]){//不删除头结点时
			binarytree.find_remove(search);//删除该值的节点及其子树
			binarytree.output();
		}
	}
	system("pause");
	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值