二叉树相关操作

节点定义

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

递归法遍历

//前序遍历
void preorderTraversal(TreeNode* root, vector<int>& result)
{
	if(root == null)
		return;
			
	result.push_back(root->val);
	Traversal(root->left, result);
	Traversal(root->right, result);
}

//中序遍历
void inorderTraversal(TreeNode* root, vector<int>& result)
{
	if(root == null)
		return;
			
	Traversal(root->left, result);
	result.push_back(root->val);
	Traversal(root->right, result);
}

//后续遍历
void postorderTraversal(TreeNode* root, vector<int>& result)
{
	if(root == null)
		return;

	Traversal(root->left, result);
	Traversal(root->right, result);		
	result.push_back(root->val);
}

非递归(迭代)遍历

利用栈实现二叉树的三种遍历,使用一个NULL空指针做标记,来确定要弹出的数据

//前序遍历
vector<int> preorderTraversal(TreeNode* root)
{
    stack<TreeNode*> st;
    vector<int> result;
    st.push(root);
    while(!st.empty())
    {
        TreeNode* tmp = st.top();
		if (tmp != nullptr)
		{
			st.pop();
			if (tmp->right != nullptr) st.push(tmp->right); //右
			if (tmp->left != nullptr) st.push(tmp->left);	//左
			st.push(tmp);								    //中
			st.push(nullptr);								//空节点做标记
		}
		else
		{
			st.pop();//空节点弹出
			tmp = st.top();
			st.pop();
			result.push_back(tmp->val);
		}
    }
return result;
}

//中序遍历
vector<int> inorderTraversal(TreeNode* root)
{
	stack<TreeNode*> st;
	vector<int> result;
	st.push(root);
	while (!st.empty())
	{
		TreeNode* tmp = st.top();
		if (tmp != nullptr)
		{
			st.pop();
			if (tmp->right != nullptr) st.push(tmp->right); //右
			st.push(tmp);								    //中
			st.push(nullptr);								//空节点做标记
			if (tmp->left != nullptr) st.push(tmp->left);	//左
		}
		else
		{
			st.pop();//空节点弹出
			tmp = st.top();
			st.pop();
			result.push_back(tmp->val);
		}
	}
	return result;
}

//后续遍历
vector<int> postorderTraversal(TreeNode* root)
{
	stack<TreeNode*> st;
	vector<int> result;
	st.push(root);
	while (!st.empty())
	{
		TreeNode* tmp = st.top();
		if (tmp != nullptr)
		{
			st.pop();
			st.push(tmp);								    //中
			st.push(nullptr);								//空节点做标记
			if (tmp->right != nullptr) st.push(tmp->right); //右
			if (tmp->left != nullptr) st.push(tmp->left);	//左
		}
		else
		{
			st.pop();//空节点弹出
			tmp = st.top();
			st.pop();
			result.push_back(tmp->val);
		}
	}
	return result;
}

判断二叉树是否对称

//递归法
class Solution
{
public:
	bool compare(TreeNode* left, TreeNode* right)
	{
		if(left == NULL && right == NULL) return true;
		else if(left == NULL || right == NULL) return false;
		else if(left->val != right->val) return false;
		
		bool outside = compare(left->left, right->right);
		bool inside = compare(left->right, right->left);
		bool isSame = outside && inside;
		
		return isSame;
	}
	
	bool isSymmetric(TreeNode* root)
	{
		if(root == NULL) return true;
		
		return compare(root->left, root->right);
	}
};

//迭代法
class Soultion
{
public:
	bool compare(TreeNode* root)
	{
		queue<TreeNode*> qu;//此处使用的队列,使用栈也可以
		if(root == NULL) return true;
		qu.push(root->left);
		qu.push(root->right);
		while(!qu.empty())
		{
			TreeNode* left = qu.top();
			qu.pop();
			TreeNode* right = qu.top();
			qu.pop();
			if(left == NULL && right == NULL) continue;
			else if(left == NULL || right == NULL) return false;
			else if(left->val !== right-val) return false;
			
			qu.push(left->left);
			qu.push(right->right);
			qu.push(left->right);
			qu.push(right->left);
		}
		return true;
	}
};

树的深度

//递归法
class Soultion
{
public:
	int maxDepth(TreeNode* root)
	{
		if(root == NULL) return 0;
		return 1 + max(maxDepth(root->left), maxDepth(root->right)); 
	}
};

//迭代法
class Solution
{
public:
	int maxDepth(TreeNode* root)
	{
		if(root == NULL) return 0;
		queue<TreeNode*> qu;
		int depth = 0;
		qu.push(root);
		while(!qu.empty())
		{
			int lon = qu.size();
			depth++;
			for(int i = 0; i < lon; i++)
			{
				TreeNode* tmp = qu.top();
				qu.top;
				if(tmp->left != NULL) qu.pus(tmp->left);
				if(tmp->right != NULL) qu.pus(tmp->right);
			}
		]
		return depth;
	}
};

二叉树所有路径

//递归、回溯
class Solution
{
public:
	void totalPath(TreeNode* root, vector<int>& path, vector<string>& strPath)
	{
		path.push_back(root->val);
		if (root->left == NULL && root->right == NULL)
		{
			string sPath;
			for (int i = 0; i < path.size() - 1; i++)
			{
				sPath += to_string(path[i]);
				sPath += "-->";
			}
			sPath += to_string(path[path.size() - 1]);
			strPath.push_back(sPath);
			return;
		}
		if (root->left != NULL)
		{
			totalPath(root->left, path, strPath);
			path.pop_back();
		}
		if (root->right != NULL)
		{
			totalPath(root->left, path, strPath);
			path.pop_back();
		}
	}
	vector<string> getTotalPath(TreeNode* root)
	{
		vector<int> path;
		vector<string> strPath;
		totalPath(root, path, strPath);
		return strPath;
	}
};

路径总和

//递归、回溯
class Solution {
private:
    bool traversal(TreeNode* cur, int count) {
        if (!cur->left && !cur->right && count == 0) return true; // 遇到叶子节点,并且计数为0
        if (!cur->left && !cur->right) return false; // 遇到叶子节点直接返回

        if (cur->left) { // 左
            count -= cur->left->val; // 递归,处理节点;
            if (traversal(cur->left, count)) return true;
            count += cur->left->val; // 回溯,撤销处理结果
        }
        if (cur->right) { // 右
            count -= cur->right->val; // 递归,处理节点;
            if (traversal(cur->right, count)) return true;
            count += cur->right->val; // 回溯,撤销处理结果
        }
        return false;
    }

public:
    bool hasPathSum(TreeNode* root, int sum) {
        if (root == NULL) return false;
        return traversal(root, sum - root->val);
    }
};

//迭代
class Solution {

public:
    bool hasPathSum(TreeNode* root, int sum) {
        if (root == NULL) return false;
        // 此时栈里要放的是pair<节点指针,路径数值>
        stack<pair<TreeNode*, int>> st;
        st.push(pair<TreeNode*, int>(root, root->val));
        while (!st.empty()) {
            pair<TreeNode*, int> node = st.top();
            st.pop();
            // 如果该节点是叶子节点了,同时该节点的路径数值等于sum,那么就返回true
            if (!node.first->left && !node.first->right && sum == node.second) return true;

            // 右节点,压进去一个节点的时候,将该节点的路径数值也记录下来
            if (node.first->right) {
                st.push(pair<TreeNode*, int>(node.first->right, node.second + node.first->right->val));
            }

            // 左节点,压进去一个节点的时候,将该节点的路径数值也记录下来
            if (node.first->left) {
                st.push(pair<TreeNode*, int>(node.first->left, node.second + node.first->left->val));
            }
        }
        return false;
    }
};

二叉树重建

class Solution2
{
private:
	TreeNode* traversal(vector<int>& inorder, vector<int>& postorder)
	{
		//后序遍历的最后一个元素是根节点
		if (postorder.size() == 0) return NULL;
		int rootValue = postorder[postorder.size() - 1];
		TreeNode* root = new TreeNode(rootValue);

		if (postorder.size() == 1) return root;

		int delimiterInder;
		for (delimiterInder = 0; delimiterInder < postorder.size(); delimiterInder++)
		{
			if (inorder[delimiterInder] == rootValue)
				break;
		}

		//中序数组,左闭右开
		vector<int> leftInorder(inorder.begin(), inorder.begin() + delimiterInder);
		vector<int> rightInorder(inorder.begin() + delimiterInder + 1, inorder.end());
		postorder.resize(postorder.size() - 1);

		//后序数组,左闭右开
		vector<int> leftPostorder(postorder.begin(), postorder.begin() + leftInorder.size());
		vector<int> rightPostorder(postorder.begin() + leftInorder.size(), postorder.end());

		root->left = traversal(leftInorder, leftPostorder);
		root->right = traversal(rightInorder, rightPostorder);
		return root;
	}
public:
	TreeNode* buildTree(vector<int>& inorder, vector<int>& postorder)
	{
		if (inorder.size() == 0 || postorder.size() == 0 || inorder.size() != postorder.size())
			return NULL;
		return traversal(inorder, postorder);
	}
};

搜索树的最小绝对值

给你一棵所有节点为非负值的二叉搜索树,请你计算树中任意两节点的差的绝对值的最小值。

class Soultion11
{
private:
	int result = INT_MAX;
	TreeNode* pre = NULL;
	vector<TreeNode*> st;
	void traversal(TreeNode* cur)
	{
		if (cur == NULL) return;
		traversal(cur->left);
		if (pre != NULL)
			result = min(result, cur->val - pre->val);
		pre = cur;//记录前一个
		traversal(cur->right);
	}
public:
	int getMin(TreeNode* root)
	{
		traversal(root);
		return result;
	}
};

class Soultion22
{
public:
	int getMinDifference(TreeNode * root)
	{
		stack<TreeNode*> st;
		TreeNode* cur = root;
		TreeNode* pre = NULL;
		int result = INT_MAX;
		while (cur != NULL || !st.empty())
		{
			if (cur != NULL)
			{
				st.push(cur);			//当前节点放进栈
				cur = cur->left;		//左
			}
			else
			{
				cur = st.top();
				st.pop();
				if (pre != NULL)		//中
				{
					result = min(result, cur->val - pre->val);
				}
				pre = cur;
				cur = cur->right;		//右
			}
		}
		return result;
	}
};

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值