C++:二叉树及相关操作

有几个定律:

  • 节点个数=边的个数+1
  • 度为2的节点个数=度为0的节点个数-1
    注:n2 + n1 + n0 = 2*n2 + n1 + 1

几种二叉树类型(中国版

  • 完全二叉树:除了右子树,只存在度为2、0的节点
  • 满二叉树:深度相同的节点度相同?自己的定义

(国际版

  • 完美二叉树:与中国版满二叉树定义相同
  • 满二叉树:只存在度为0、2的节点

完全二叉树

  • 节点的编号可以由父亲节点编号获得,可以去记录数组
#include<iostream>
using std::cout;
using std::endl;
class Node {
public:
    int data;
    Node *lchild, *rchild;
    Node(int _data) {
        data = _data;
        lchild = NULL;
        rchild = NULL;
    }
    ~Node() {
        if (lchild != NULL) {
            delete lchild;
        }
        if (rchild != NULL) {
            delete rchild;
        }
    }
    void preorder() {
        cout << data << " ";
        if (lchild != NULL) {
            lchild->preorder();
        }
        if (rchild != NULL) {
            rchild->preorder();
        }
    }
    void inorder() {
        if (lchild != NULL) {
            lchild->inorder();
        }
        cout << data << " ";
        if (rchild != NULL) {
            rchild->inorder();
        }
    }
    // 请在下面实现类 Node 的后序遍历方法 postorder
	void postorder() {
        if (lchild != NULL) {
            lchild->postorder();
        }
        if (rchild != NULL) {
            rchild->postorder();
        }
        cout << data << " ";
    }
};
class BinaryTree {
private:
    Node *root;
public:
    BinaryTree() {
        root = NULL;
    }
    ~BinaryTree() {
        delete root;
    }
    void build_demo() {
        root = new Node(1);
        root->lchild = new Node(2);
        root->rchild = new Node(3);
        root->lchild->lchild = new Node(4);
        root->lchild->rchild = new Node(5);
        root->rchild->rchild = new Node(6);
    }
    void preorder() {
        root->preorder();
    }
    void inorder() {
        root->inorder();
    }
    // 请在下面实现类 BinaryTree 的后序遍历方法 postorder
	void postorder(){
        root->postorder();
    }
};
int main() {
    BinaryTree binarytree;
    binarytree.build_demo();
    binarytree.preorder();
    cout << endl;
    binarytree.inorder();
    cout << endl;
	binarytree.postorder();
    cout << endl;
    return 0;
}
已知先序、中序求后序
#include<iostream>
#include<string>
using std::cout;
using std::endl;
using std::string;
class Node {
public:
    int data;
    Node *lchild, *rchild;
    Node(int _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] - '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;
    }
};
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();
    }
};
int main() {
    string pre_str = "136945827";
    string in_str = "963548127";
	BinaryTree binarytree(pre_str, in_str, in_str.length());
    binarytree.postorder();
    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* 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();
					temp->lchild = p;
				}else if(k == 1){
					temp = s.top();
					temp->rchild = p;
				}
			}
		}
		return root;
	}

    void level_output(){//前提root!=NULL
    	cout << data;
    	queue<Node *> q;
        if (lchild != NULL){
            q.push(lchild);
        }
        if (rchild != NULL){
            q.push(rchild);
        }    	
    	while(!q.empty()){
    		cout << " ";
    		cout << q.front()->data;
    		if (q.front()->lchild != NULL){
    			q.push(q.front()->lchild);
    		}
    		if (q.front()->rchild != NULL){
    			q.push(q.front()->rchild);
    		}
    		q.pop();
    	}
    }

};

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 level_output(){
    	if (root == NULL){
			return;
		}
    	root->level_output();
    }

};

int main() {
	string str;
	char ch;
	//while ((ch = getchar()) != '\n') str+=ch;
	while (~scanf("%c", &ch)) str+=ch;
	BinaryTree binarytree(str);
	binarytree.level_output();
    cout << endl;

    return 0;
}

其中层次遍历输出这个,我觉得没什么问题,但测评系统没通过,这里记录一下;

还有一个三元组建立二叉树的问题;我先不写了简单记录思路:

  • 输入为n行,或许可以用字符串数组记录,然后n%3 = 0的是根节点,n%3 = 1的是子节点,=2的是左右。
  • 将字符串数组传入函数,函数中设一个队列q(因为是顺序表的顺序),
一个为^的是根;
push();
while(字符串没结束){
	if 第一个字符等于q.front(){
		if 第三个字符等于L{
		q.front()->lchild = new...;q.push(q.front()->lchild);}
		if 第三个字符等于R{
		q.front()->rchild = new...;q.push(q.front()->rchild);}
	}else{
		q.pop();
	}
}
return;
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值