关于树的算法题(C++)

前段时间总结了一下关于树的算法,上传到博客,以后方便查看。

目录

二叉树的下一个节点

二叉树的镜像

对称二叉树

树的子结构

二叉树的路径

打印二叉树

重建二叉树

二叉搜索树第K大的节点

二叉搜索树变成双向链表

二叉搜索树的后序遍历

序列化二叉树

平衡二叉树


二叉树的下一个节点

/*
二叉树的下一个节点
给定一颗二叉树和其中一个节点,找到中序遍历的下一个节点,树中有指向左、右两个子树的指针,还有
指向父节点的指针
*/

Struct TreeNode{
	int val;
	TreeNode* left;
	TreeNode* right;
	TreeNode* parent;
	TreeNode(int x) : val(x), left(NULL), rihgt(NULL), parent(NULL){}
};


class Solution{
public:
	TreeNode* getNext(TreeNode* node){
		if(node == NULL){
			return NULL;
		}
		if(node->right != NULL){           //判断节点的右子树是否为空
			TreeNode* next = node->right;
			while(next->left != NULL){
				next = next->left;
			}
			return next;
		}
		while(node->parent != NULL){       //判断父节点是否为空
			TreeNode* next = node->parent;
			if(next->left == node){
				return next;
			}
			node = next;
		}
		return NULL;
	}
}

二叉树的镜像

/*
二叉树的镜像
操作给定的二叉树,将其变换为源二叉树的镜像。
*/

struct  TreeNode{
	int val;
	TreeNode* left;
	TreeNode* right;
	TreeNode(int x) : val(x), left(NULL), right(NULL) {}
};

class Solution
{
public:
	Solution();
	~Solution();
	
	// 递归版本
	void MirrorRecur(TreeNode* node){
		if(node == NULL){
			return;
		}
		TreeNode* tmp = node->left;
		node->left = node->right;
		node->right = tmp;
		MirrorRecur(node->left);
		MirrorRecur(node->right);
	}


	// 非递归版本
	void MirrorNonrecur(TreeNode* node){
		if(node == NULL){
			return;
		}
		stack<TreeNode*> tmp;
		tmp.push(node);
		while(!tmp.empty()){
			TreeNode* cur = tmp.top();
			tmp.pop();
			if(cur->left != NULL || cur->right != NULL){
				TreeNode* tmp = cur->left;
				cur->left = cur->right;
				cur->right = tmp;
			}
			if(cur->right != NULL){
				tmp.push(cur->right);
			}
			if(cur->left != NULL){
				tmp.push(cur->left);
			}
		}
	}
};

对称二叉树

/*
对称二叉树
实现一个函数,判断一颗二叉树是不是对称二叉树
*/

class Solution
{
public:
	Solution();
	~Solution();
	
	// 递归版本
	bool isSymRecur(TreeNode* node){
		if(node == NULL){
			return true;
		}
		return isSymCore(node->left, node->right);
	}
	bool isSymRecurCore(TreeNode* node1, TreeNode* node2){
		if(node1 == NULL && node2 == NULL){
			return true;
		}
		if(node1 == NULL || node2 == NULL || node1->val != node2->val){
			return false;
		}
		return isSymCore(node1->left, node2->right) && isSymCore(node1->rihgt, node2->left);
	}


	// 非递归版本
	bool isSymNonrecur(TreeNode* node){
		if(node == NULL){
			return true;
		}
		stack<TreeNode*> s1;
		stack<TreeNode*> s2;
		s1.push(node);
		s2.push(node);
		while(!s1.empty() && s2.empty()){
			TreeNode* cur1 = s1.top();
			s1.pop();
			TreeNode* cur2 = s2.top();
			s2.pop();
			if(cur1 == NULL && cur2 == NULL){
				continue;
			}
			if(cur1 == NUL || cur2 == NULL || cur1->val != cur2->val){
				return false;
			}
			s1.push(cur1->rihgt);
			s1.push(cur1->left);
			s2.push(cur2->left);
			s2.push(cur2->right);
		}
		if(s1.empty() && s2.empty()){
			return true;
		}
		return false;
	}

};

树的子结构

/*
树的子结构
输入两棵二叉树A、B,判断B是不是A的子结构(ps:我们约定空树不是任意一个树的子结构)
*/

class Solution
{
public:
	Solution();
	~Solution();
	
	// 递归版本
	bool hasSubtreeRecur(TreeNode* node1, TreeNode* node2){
		if(node1 == NULL || node2 == NULL){
			return false;
		}
		return isSubtreeRecur(node1, node2)
			|| hasSubtreeRecur(node1->left, node2)
			|| hasSubtreeRecur(node1->right, node2);
	}
	bool isSubtreeRecur(TreeNode* node1, TreeNode* node2){
		if(node2 == NULL){
			return true;
		}
		if(node1 == NULL){
			return false;
		}
		if(node1->val == node2->val){
			return isSubtreeRecur(node1->left, node2->left) 
			&& isSubtreeRecur(node1->right, node2->right);
		}
		return false;
	}

	// 非递归版本
	bool hasSubtreeNonrecur(TreeNode* node1, TreeNode* node2){
        if(node1 == NULL || node2 == NULL){
            return false;
        }
        queue<TreeNode*> tmp;
        tmp.push(node1);
        while(!tmp.empty()){
            TreeNode* cur = tmp.front();
            tmp.pop();
            bool target = false;
            if(cur->val == node2->val){
                target = isSubtree(cur, node2);
            }
            if(target){
                return true;
            }
            if(cur->left){
                tmp.push(cur->left);
            }
            if(cur->right){
                tmp.push(cur->right);
            }
        }
        return false;
    }
    
    bool isSubtreeNonrecur(TreeNode* node1, TreeNode* node2){
        stack<TreeNode*> s1;
        stack<TreeNode*> s2;
        s1.push(node1);
        s2.push(node2);
        while(!s1.empty() && !s2.empty()){
            TreeNode* cur1 = s1.top();
            s1.pop();
            TreeNode* cur2 = s2.top();
            s2.pop();
            if(cur2 == NULL){
                continue;
            }
            if(cur1 == NULL || cur1->val != cur2->val){
                return false;
            }
            s1.push(cur1->right);
            s1.push(cur1->left);
            s2.push(cur2->right);
            s2.push(cur2->left);
        }
        if(s2.empty()){
            return true;
        }
        return false;
    }
};

二叉树的路径

/*
二叉树中的和为某一值的路径
输入一棵二叉树和一个整数,打印二叉树中节点值的和为输入整数的路径。从树根节点往下直到叶节点
形成一条路径。
*/

class Solution
{
public:
	Solution();
	~Solution();
	

	vector<vector<int> > findPath(TreeNode* root, int num){
		vector<vector<int> > all;
		if(root ==  NULL){
			return all;
		}
		vector<int> path;
		findPathCore(root, all, path, num);
		return all;
	}

	void findPathCore(TreeNode* root, vector<vector<int> >& all, vector<int>& path, 
		int num){
		if(num < root->val){
			return;
		}
		path.push_back(root->val);
		if(num == root->val && root->left == NULL && root->right == NULL){
			all.push_back(path);
			path.pop_back();
			return;
		}
		if(root->left){
			findPathCore(root->left, all, path, num - root->val);
		}
		if(root->right){
			findPathCore(root->right, all, path, num - root->val);
		}
		path.pop_back();
	}
};

打印二叉树

/*
从上到下打印二叉树
从上到下按层打印二叉树,同一层结点从左至右输出。每一层输出一行。
*/

class Solution
{
public:
	Solution();
	~Solution();
	
	vector<vector<int> > print(TreeNode* root){
		vector<vector<int> > all;
		if(root == NULL){
			return all;
		}
		queue<TreeNode*> tmp;
		tmp.push(root);
		while(!tmp.empty()){
			vector<int> path;
			int size = tmp.size();
			for(int i = 0; i < size; i++){
				TreeNode* cur = tmp.front();
				tmp.pop();
				path.push_back(cur->val);
				if(cur->left){
					tmp.push(cur->left);
				}
				if(cur->right){
					tmp.push(cur->right);
				}
			}
			all.push_back(path);
		}
		return all;
	}
};

重建二叉树

/*
重建二叉树
输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树。
*/

class Solution
{
public:
	Solution();
	~Solution();
	
	TreeNode* reBuildBinaryTree(vector<int> pre, vector<int> vin){
		if(pre.size() == 0 || pre.size() != vin.size()){
			return NULL;
		}
	 	vector<int> preL, preR, vinL, vinR;
	 	int tar = 0;
	 	while(pre[0] != vin[tar]){
	 		tar++;
	 	}
	 	for(int i = 0; i < tar; i++){
	 		preL.push_back(pre[i + 1]);
	 		vinL.push_back(vin[i]);
	 	}
	 	for(int i = tar + 1; i < pre.size(); i++){
	 		preR.push_back(pre[i]);
	 		vinL.push_back(vin[i]);
	 	}
	 	TreeNode* cur = new TreeNode(pre[0]);
	 	cur->left = reBuildBinaryTree(preL, vinL);
	 	cur->right = reBuildBinaryTree(preR, vinR);
	 	return cur;
	}
};

二叉搜索树第K大的节点

/*
二叉搜索树的第K大的节点
给定一棵二叉搜索树,请找出其中的第k小的结点
*/

class Solution
{
public:
	Solution();
	~Solution();
	

	TreeNode* kthNodeRecur(TreeNode* root, int k){
		if(root == NULL || k <= 0){
			return NULL;
		}
		return kthNodeRecurCore(root, k);
	}

	TreeNode* kthNodeRecurCore(TreeNode* root, int& k){
		if(root == NULL || k <= 0){
			return NULL;
		}
		TreeNode* target = NULL;
		if(root->left){
			target = kthNodeRecurCore(root->left, k);
		}
		if(target == NULL){
			k--;
			if(k == 0){
				target = root;
			}
		}
		if(target == NULL && root->right){
			target = kthNodeRecurCore(root->right, k);
		}
		return target;
	}

	TreeNode* kthNodeNonrecur(TreeNode* root, int k){
		if(root == NULL || k <= 0){
			return NULL;
		}
		stack<TreeNode*> tmp;
		TreeNode* cur = root;
		while(cur != NULL || !tmp.empty()){
			if(cur != NULL){
				tmp.push(cur);
				cur = cur->left;
			}
			else{
				cur = tmp.top();
				tmp.pop();
				k--;
				if(k == 0){
					return cur;
				}
				cur = cur->right;
			}
		}
		return NULL;
	}
};

二叉搜索树变成双向链表

/*
二叉搜索树和双向链表
输入二叉搜索树,将二叉搜索树转换成一个排序的双向链表
*/

class Solution
{
public:
	Solution();
	~Solution();
	

	TreeNode* convertRecur(TreeNode* root){
		if(root == NULL){
			return;
		}
		TreeNode* pre = NULL;
		convertRecurCore(root, pre);
		while(root->left != NULL){
			root = root->left;
		}
		return root;
	}

	void convertRecurCore(TreeNode* root, TreeNode* &pre){
		if(root == NULL){
			return;
		}
		convertRecurCore(root->left, pre);
		root->left = pre;
		if(pre != NULL){
			pre->right = root;
		}
		pre = root;
		convertRecurCore(root->right, pre);
	}


	TreeNode* convertNonrecur(TreeNode* root){
		if(root == NULL){
			return NULL;
		}
		stack<TreeNode*> tmp;
		TreeNode* cur = root;
		TreeNode* pre = NULL;
		while(cur != NULL || !tmp.empty()){
			if(cur != NULL){
				tmp.push(cur);
				cur = cur->left;
			}
			else{
				cur = tmp.top();
				tmp.pop();
				cur->left = pre;
				if(pre != NULL){
					pre->right = cur;
				}
				pre = cur;
				cur = cur->right;
			}
		}
		while(root->left != NULL){
			root = root->left;
		}
		return root;
	}
};

二叉搜索树的后序遍历

/*
二叉搜索树的后序遍历序列
输入一个整数数组,判断该数组是不是某二叉搜索树的后序遍历结果
*/

class Solution
{
public:
	Solution();
	~Solution();
	

	bool verifySquenceOfBST(vector<int> sequence){
		if(sequence.size() == 0){
			return false;
		}
		return verifySquenceOfBSTCore(sequence, 0, sequence.size() - 1);
	}

	bool verifySquenceOfBSTCore(vector<int> sequence, int start, int end){
		if(start < 0 || end >= sequence.size() || start > end){
			return false;
		}
		int i = start; 
		while(sequence[i] < sequence[end]){
			i++;
		}
		for(int j = i; j < end; j++){
			if(sequence[j] < sequence[size]){
				return false;
			}
		}
		return verifySquenceOfBSTCore(sequence, start, i - 1) && 
			verifySquenceOfBSTCore(sequence, i, end - 1);

	}

};

序列化二叉树

/*
序列化二叉树
实现两个函数,分别序列化和反序列化二叉树
*/

class Solution
{
public:
	Solution();
	~Solution();
	

	char* serialize(TreeNode* root){
		if(root == NULL){
			return NULL;
		}
		string str;
		serializeCore(root, str);
		char* tmp = new char[str.size() + 1];
		for(int i = 0; i < str.size(); i++){
			tmp[i] = str[i];
		}
		tmp[str.size()] = '\0';
		return tmp;
	}

	void serializeCore(TreeNode* root, string& str){
		if(root == NULL){
			str += '#';
			return;
		}
		str += to_string(root->val);
		str += ',';
		serializeCore(root->left, str);
		serializeCore(root->right, str);
	}


	TreeNode* deserialize(char* str){
		if(str == NULL){
			return NULL;
		}
		return deserializeCore(str);
	}
	TreeNode* deserializeCore(char* &str){
		if(*str == '#'){
			str++;
			return NULL;
		}
		int num = 0;
		while(*str != '/0' && *str != ','){
			num = num * 10 + (*str - '0');
			str++;
		}
		TreeNode* tmp = new TreeNode(num);
		if(*str == '\0'){
			return tmp;
		}
		else{
			str++;
		}
		tmp->left = deserializeCore(str);
		tmp->right = deserializeCore(str);
		return tmp;
	}
};

二叉树的深度

/*
二叉树的深度
输入一棵二叉树的根节点,求该树的深度
*/

class Solution
{
public:
	Solution();
	~Solution();
	
	int getTreeDepthRecur(TreeNode* node){
		if(node == NULL){
			return 0;
		}
		int left = getTreeDepthRecur(node->left);
		int right = getTreeDepthRecur(node->right);
		return (left > right) ? (left + 1) : (right + 1);
	}


	int getTreeDepthNonrecur(TreeNode* node){
		if(node == NULL){
			return 0;
		}
		queue<TreeNode*> tmp;
		tmp.push(node);
		int depth;
		while(!tmp.empty()){
			depth++;
			int size = tmp.size();
			for(int i = 0; i < size; i++){
				TreeNode* cur = tmp.front();
				tmp.pop();
				if(cur->left){
					tmp.push(cur->left);
				}
				if(cur->right){
					tmp.push(cur->right);
				}
			}
		}
		return depth;
	}
};

平衡二叉树

/*
平衡二叉树
输入一颗二叉树的根节点,判断该树是不是平衡二叉树。如果某二叉树任意节点的左右子树深度相差
不超过1,那么它就是一颗平衡二叉树。
*/

class Solution
{
public:
	Solution();
	~Solution();
	
	bool isBalanced(TreeNode* root){
		if(root == NULL){
			return false;
		}
		int depth = 0;
		return isBalanced(root, depth);
	}
	bool isBalanced(TreeNode* root, int &depth){
		if(root == NULL){
			depth = 0;
			return true;
		}
		int left = 0, right = 0;
		if(isBalanced(root->left, left) && isBalanced(root->right, right)){
			int diff = left - right;
			if(abs(diff) <= 1){
				depth = left > right ? (left + 1) : (right + 1);
				return true;
			}
		}
		return false;
	}
};

 

  • 2
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值