二叉树专题

反转二叉树

有一个问题,若没有node->lchild = reverse(node->lchild);而是直接reverse(node->lchild);就会宝座

#include<iostream>
#include<string>
using std::cin;
using std::cout;
using std::endl;
using std::string;
class Node {
public:
    char data;
    Node *lchild, *rchild;
    Node(char _data) {
        data = _data;
        lchild = NULL;
        rchild = NULL;
    }
    ~Node() {
        if (lchild != NULL) {
            delete lchild;
        }
        if (rchild != NULL) {
            delete rchild;
        }
    }
    void postorder() {
        if (lchild != NULL) {
            lchild->postorder();
        }
        if (rchild != NULL) {
            rchild->postorder();
        }
        cout << data;
    }
    // 请在下面实现建立二叉树的方法 build
	Node* build(const string &pre_str, const string &in_str, int len){
        Node *p = new Node(pre_str[0]);
        int pos = in_str.find(pre_str[0]);
        if (pos > 0){
            p->lchild = build(pre_str.substr(1, pos), in_str.substr(0, pos), pos);
        }
        if (len - pos - 1 > 0){
            p->rchild = build(pre_str.substr(pos + 1), in_str.substr(pos + 1), len - pos - 1);
        }
        return p;
    }
    
    Node* reverse(Node *node){
        if (node == NULL){
            return NULL;
        }

        Node *temp = node->lchild;
		node->lchild = node->rchild;
		node->rchild = temp;

		node->lchild = reverse(node->lchild);
		node->rchild = reverse(node->rchild);

        return node;
    }
};
class BinaryTree {
private:
    Node *root;
public:
    BinaryTree() {
        root = NULL;
    }
    ~BinaryTree() {
        delete root;
    }
    // 请在下面实现构造函数
    BinaryTree(const string &pre_str, const string &in_str, int len){
        root = root->build(pre_str, in_str, len);
    }

    void postorder() {
        root->postorder();
    }
    
    void reverse(){
        root->reverse(root);
    }
};
int main() {
    string pre_str = "";
    string in_str = "";
    cin >> pre_str;
    cin >> in_str;
	BinaryTree binarytree(pre_str, in_str, in_str.length());
    binarytree.postorder();
    cout << endl;
    binarytree.reverse();
    binarytree.postorder();
    cout << endl;
    
    return 0;
}

删除二叉树中的节点

这题要求用广义表输入,并在递归删除某个节点后,再使用广义表输出。
这里有几个问题:

  • 删除节点时,我第一遍写的是直接void delete_node(const char &c),大意是没有再把root赋值一遍,直接使用传入的root值,并在此基础上使用data、lchild…结果是,删除过程没问题,但调用generalized_output函数时不输出,好像走丢了一样(root指针指向错误??)。后来,把函数类型改为可返回节点,返回一个新的root值,就OK。
  • 在写二叉树生成广义表时,误写为return lchild->generalized_output();,后来对照preorder才写对,大概知道这个逻辑是错的,但不知道具体原因。
  • 在测试组里有一例是空字符串,也就是二叉树为空。但cin和scanf会把空白符跳过!!一开始就输入回车,他仍然会等着你输入。。rlgl,后来还是用char的方法判断回车,但不知道s+=ch的原理。
#include<iostream>
#include<string>
#include<stack>
using std::cin;
using std::cout;
using std::endl;
using std::string;
using std::stack;

class Node {
public:
    char data;
    Node *lchild, *rchild;
    Node(char _data) {
        data = _data;
        lchild = NULL;
        rchild = NULL;
    }
    ~Node() {
        if (lchild != NULL) {
            delete lchild;
        }
        if (rchild != NULL) {
            delete rchild;
        }
    }

	Node* generalized_build(const string &input_str){
		stack<Node *> s;
		Node *root = NULL;
		Node *p, *temp;
		if (input_str == ""){
			return NULL;
		}
		int k = -1;
		for (int i = 0; i < input_str.length(); i++){
			if (input_str[i] == '('){
				k = 0;
				s.push(p);
			}else if(input_str[i] == ','){
				k = 1;
			}else if(input_str[i] == ')'){
				s.pop();
			}else{//字母
				p = new Node(input_str[i]);
				if (k == -1){
					//作为根节点入栈
					root = p;
					s.push(root);
				}else if(k == 0){
					temp = s.top();
					//s.pop();
					temp->lchild = p;
					//s.push(temp);
				}else if(k == 1){
					temp = s.top();
					//s.pop();
					temp->rchild = p;
					//s.push(temp);
				}
			}
		}
		return root;
	}

	void generalized_output(){
		cout << data;
		if (lchild != NULL || rchild != NULL){
			cout << "(";
		}
		if (lchild != NULL){
			lchild->generalized_output();
		}
		if (rchild != NULL){
            cout << ",";
			rchild->generalized_output();
		}
		if (lchild != NULL || rchild != NULL){
			cout << ")";
		}
	}

	Node* delete_node(Node *node, const char &c){
		if (node->data == c){
			if (node->lchild != NULL){
				delete node->lchild;
			}
			if (node->rchild != NULL){
				delete node->rchild;
			}
			return NULL;
		}else{
			if (node->lchild != NULL){
				node->lchild = node->lchild->delete_node(node->lchild, c);
			}
			if (rchild != NULL){
				node->rchild = node->rchild->delete_node(node->rchild, c);
			}
		}
		return node;
	}

};

class BinaryTree {
private:
    Node *root;
public:
    BinaryTree() {
        root = NULL;
    }
    ~BinaryTree() {
        delete root;
    }

    BinaryTree(const string &input_str){
        if (input_str.length() == 0){
            root = NULL;
        }
		root = root->generalized_build(input_str);
	}

    void generalized_output(){
    	if (root == NULL){
    		return;
    	}
    	root->generalized_output();
    }

    void delete_node(const char &c){
        if (root == NULL){
    		return;
    	}
    	root = root->delete_node(root, c);
    }

};

int main() {
    char delete_ch;
    string str = "";
	char ch;
	while ((ch = getchar()) != '\n') str+=ch; //此处可以do stuff
    cin >> delete_ch;
    BinaryTree binarytree(str);
    binarytree.delete_node(delete_ch);
    binarytree.generalized_output();
    cout << endl;

    return 0;
}

由顺序表建立完全二叉树

#include<iostream>
#include<string>
#include<cstring>
#include<stack>
#include<queue>
using std::cin;
using std::cout;
using std::endl;
using std::string;
using std::stack;
using std::queue;

class Node {
public:
    char data;
    Node *lchild, *rchild;
    Node(char _data) {
        data = _data;
        lchild = NULL;
        rchild = NULL;
    }
    ~Node() {
        if (lchild != NULL) {
            delete lchild;
        }
        if (rchild != NULL) {
            delete rchild;
        }
    }

	Node* build_complete(char *p){//p为字符串指针,q为队列指针
		if (p[0] == '$'){
			return NULL;
		}
		Node *node = new Node(p[0]);
		p = std::strtok(NULL," ");

		queue<Node *> q;
		q.push(node);

		int i = 0;
		while(p[0] != '$'){
			if (i % 2 == 0){
				q.front()->lchild = new Node(p[0]);
				q.push(q.front()->lchild);
				p = std::strtok(NULL," ");
				i++;
			}else{
				q.front()->rchild = new Node(p[0]);
				q.push(q.front()->rchild);
				q.pop();
				p = std::strtok(NULL," ");
				i++;
			}
		}
		return node;
	}

	void generalized_output(){
		cout << data;
		if (lchild != NULL || rchild != NULL){
			cout << "(";
		}
		if (lchild != NULL){
			lchild->generalized_output();
		}
		if (rchild != NULL){
            cout << ",";
			rchild->generalized_output();
		}
		if (lchild != NULL || rchild != NULL){
			cout << ")";
		}
	}

};

class BinaryTree {
private:
    Node *root;
public:
    BinaryTree() {
        root = NULL;
    }
    ~BinaryTree() {
        delete root;
    }

    BinaryTree(char *p){
    	root = root->build_complete(p);
    }

    void generalized_output(){
    	if (root == NULL){
    		return;
    	}
    	root->generalized_output();
    }


};

int main() {
	string str;
	char ch;
	while (~scanf("%c", &ch)) str+=ch;
	//while ((ch = getchar()) != '\n') str+=ch;
	char *cstr = new char [str.length()+1];
	strcpy (cstr, str.c_str());
	char *p = std::strtok(cstr," ");
	BinaryTree binarytree(p);
	binarytree.generalized_output();
    cout << endl;

    return 0;
}

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值