二叉树相关算法总结实现

二叉树相关算法总结实现

二叉树作为基本的数据结构,在一些算法面试中会经常遇到,现总结如下。基本算法思想就不介绍了,代码中关键处会有注释。程序全以C++语言实现,并跟一个main函数的简单测例。

二叉树数据结构的定义

struct TreeNode
{
    int val;
    TreeNode *left;
    TreeNode *right;
    TreeNode(int x) : val(x), left(NULL), right(NULL) {}
};
  1. 二叉树的最大深度
int maxDepth(TreeNode* root) 
{
    if(root==NULL)
        return 0;
    int maxle=maxDepth(root->left);
    int maxri=maxDepth(root->right);
    return  max(maxle,maxri)+1;
}
  1. 前序遍历 递归
vector<int> preorder(TreeNode* root) 
{
	vector<int> res;
	preorder(root, res);
	return res;
}
void preorder(TreeNode* root, vector<int> &res)
{
	if(root == NULL) 
		return;
	res.push_back(root->val);
	preorder(root->left, res);
	preorder(root->right,res);
} 
  1. 前序遍历 非递归
vector<int> preorder_(TreeNode* root) 
{
	vector<int> res;
	if(root == NULL)
		return res;
	stack<TreeNode*> sta;
	sta.push(root);
	while(!sta.empty())
	{
		TreeNode* node = sta.top();
		sta.pop();
		res.push_back(node->val);
		if(node->right)
			sta.push(node->right);
		if(node->left)
			sta.push(node->left);
	}
	return res;
}
  1. 中序遍历 递归
vector<int> inorder(TreeNode* root) 
{
	vector<int> res;
	inorder(root,res);
	return res;    	
}

void inorder(TreeNode* root, vector<int> &res) 
{
	if(root == NULL)
		return;
	inorder(root->left, res);
	res.push_back(root->val);
	inorder(root->right, res);
}
  1. 中序遍历 非递归
vector<int> inorder_(TreeNode* root) 
{
	vector<int> res;
	if(root == NULL)
		return res;
	stack<TreeNode*> sta;
	TreeNode* node = root;
	while(!sta.empty() || node != NULL)
	{
		while(node != NULL)
		{
			sta.push(node);
			node = node->left;	
		}	
		if(!sta.empty())
		{
			node = sta.top();
			sta.pop();
			res.push_back(node->val);
			node = node->right;
		}
	} 
	return res;
}

  1. 后序遍历 递归
vector<int> postorder(TreeNode* root) 
{
	vector<int> res;
	postorder(root, res);
	return res; 
}

void postorder(TreeNode* root, vector<int> &res) 
{
	if(root == NULL) 
		return;
	postorder(root->left, res);
	postorder(root->right, res);
	res.push_back(root->val);
}

  1. 后序遍历 非递归 实现1:
vector<int> postorder_(TreeNode* root) 
{
	vector<int> res;     
	stack< pair<TreeNode *, bool> > s;
	s.push(make_pair(root, false));
	bool visited;
	while(!s.empty())
	{
		root = s.top().first;
		visited = s.top().second;
		s.pop();
		if(root == NULL)
			continue;
		if(visited)
		{
			res.push_back(root->val);
		}
		else
		{
			s.push(make_pair(root, true));
			s.push(make_pair(root->right, false));
			s.push(make_pair(root->left, false));
		}
	}
	return res;
}

  1. 后序遍历 非递归 实现2:
vector<int> postorder_(TreeNode* root) 
{
	vector<int> res;     
	if (root == NULL) 
		return res;
	stack<TreeNode*> sta;
	sta.push(root);
	while(!sta.empty()) 
	{
		TreeNode* node = sta.top();
		sta.pop();
		res.push_back(node->val);
		// 实现逆序
		if(node->left)
			sta.push(node->left);
		if(node->right)
			sta.push(node->right);

	}
	// 将结果进行逆序
	reverse(res.begin(), res.end());
	return res;
}

  1. 层序遍历 实现1:
vector<vector<int> > levelOrder(TreeNode* root) 
{
	vector<vector<int> > res;
	if(root==NULL)
		return  res;
	queue<pair<TreeNode*, int> > q;
	q.push(make_pair(root,0));
	while(!q.empty())
	{
		TreeNode* node=q.front().first;
		int level=q.front().second;
		q.pop();
		if(level==res.size())
			res.push_back(vector<int>());
		res[level].push_back(node->val);
		if(node->left)
			q.push(make_pair(node->left,level+1));
		if(node->right)
			q.push(make_pair(node->right,level+1));
	}
	return res;
}

  1. 层序遍历 实现2:
vector<vector<int> > levelOrder(TreeNode* root) 
{
	vector<vector<int> > res;
	vector<int> r;
	if(root==NULL)
		return  res;
	queue<TreeNode*> q;
	q.push(root);
	while(!q.empty())
	{
		r.clear();
		int count = q.size();
		while(count > 0)
		{
			TreeNode* node=q.front();
			r.push_back(node->val);
			q.pop();
			count--;
			if(node->left)
				q.push(node->left);
			if(node->right)
				q.push(node->right);
		}
		res.push_back(r);           
	}
	return res;
}

  1. 层序打印
void printlevelorderTreeNode(vector<vector<int> > &ress)
{
	for(int i = 0; i < ress.size(); i++)
   	{
   		for(int j = 0; j < ress[i].size(); j++)
   			cout<<ress[i][j]<<" ";
   		cout<<endl;
	}	
}
  1. 前中后序打印
void printorderTreeNode(vector<int> &res)
{
	for(int i = 0; i < res.size(); i++)
   		cout<<res[i]<<" ";
}
  1. 中序后序遍历重建二叉树
TreeNode* helperInPos(vector<int>& inorder, vector<int>& postorder, int instart, int inend, int postart, int poend)
{
	if(instart > inend || postart > poend)
		return NULL;
    TreeNode *node = new TreeNode(postorder[poend]);
	int i = 0;
	//遍历中序,找到树的根结点
	for(i = instart; i< inorder.size(); i++)
	{
		if(inorder[i] == node->val)
			break;
	}
	//i-instart是inorder中根结点到左边起始点的距离
	node->left = helperInPos(inorder, postorder, instart, i - 1, postart, postart + i - instart - 1);
	node->right = helperInPos(inorder, postorder, i + 1, inend , postart + i - instart, poend - 1);
	return node;
}

TreeNode* buildTreeInPos(vector<int>& inorder, vector<int>& postorder) 
{
		return helperInPos(inorder, postorder, 0, inorder.size() - 1, 0, postorder.size() - 1);    
}
  1. 前序中序遍历重二叉树
TreeNode* helperPreIn(vector<int>& preorder, vector<int>& inorder, int prestart, int preend, int instart, int inend)
{
	if(prestart > preend || instart > inend)
	{
		return NULL;
	}

	TreeNode* node =new TreeNode(preorder[prestart]);
	int i;
	for(i = instart; i <= inend; i++)
	{
		if(inorder[i] == node->val)
		{
			break;
		}
	}

	node->left=helperPreIn(preorder, inorder, prestart + 1, prestart + i - instart, instart, i - 1);
	node->right=helperPreIn(preorder , inorder, prestart + i - instart + 1, preend, i + 1, inend);
	return node;
}

TreeNode* buildTreePreIn(vector<int>& preorder, vector<int>& inorder) 
{
	return helperPreIn(preorder, inorder, 0, preorder.size() - 1, 0, inorder.size() - 1);
}

  1. main函数
int main()
{
	//****案例1**** 
	    /
        //      5      //
        //    /   \    //
        //   3    6    //
        //  / \    \   //
        // 2  4     8  //
        /
    TreeNode* root;
    root = new TreeNode(5);
    root->left = new TreeNode(3);
    root->right = new TreeNode(6);
    root->left->left= new TreeNode(2);
    root->left->right= new TreeNode(4);
    root->right->right= new TreeNode(8);
    
     
    
    vector<int> res;
    
    // 递归前中后序遍历
	cout<<"****递归前中后序遍历****"<<endl;
	
    // 前序遍历
    cout<<"****前序遍历 递归****"<<endl;
	res = Solution().preorder(root);
	Solution().printorderTreeNode(res);
	cout<<endl<<endl;
		
	// 中序遍历
	cout<<"****中序遍历 递归****"<<endl; 
	res = Solution().inorder(root);
	Solution().printorderTreeNode(res);
	cout<<endl<<endl;
	
	// 后序遍历
	cout<<"****后序遍历 递归****"<<endl; 
	res = Solution().postorder(root);
	Solution().printorderTreeNode(res);
	cout<<endl<<endl;
	
	cout<<endl<<endl;
	// 非递归前中后序遍历
	cout<<"****非递归前中后序遍历****"<<endl;
	
    // 前序遍历 非递归 
    cout<<"****前序遍历 非递归****"<<endl;
	res = Solution().preorder_(root); 
	Solution().printorderTreeNode(res);
	cout<<endl<<endl;
	
	// 中序遍历 非递归 
	cout<<"****中序遍历 非递归****"<<endl; 
	res = Solution().inorder_(root);
	Solution().printorderTreeNode(res);
	cout<<endl<<endl;
	
	// 后序遍历 非递归 
	cout<<"****后序遍历 非递归****"<<endl; 
	res = Solution().postorder_(root);
	Solution().printorderTreeNode(res);
	cout<<endl<<endl;
	
	
	// 层序遍历
	cout<<"****层序遍历****"<<endl; 
	vector<vector<int> > ress;
	ress = Solution().levelOrder(root);
	Solution().printlevelorderTreeNode(ress);
	cout<<endl; 
	
    return 0;
} 

因为平时刷LeetCode的缘故,加上以上部分算法其实就是LeetCode里的原题,所以所有算法我都放在了Solution类中。以下以一个简单的最大深度的作为例子:

#include"iostream"
#include"vector"
#include"queue"
#include"stack"
#include"algorithm"

using namespace std;

struct TreeNode
{
    int val;
    TreeNode *left;
    TreeNode *right;
    TreeNode(int x) : val(x), left(NULL), right(NULL) {}
};
class Solution
{
public:
	
	// 二叉树的最大深度 LeetCode 104 
	int maxDepth(TreeNode* root) 
    {
        if(root==NULL)
            return 0;
        int maxle=maxDepth(root->left);
        int maxri=maxDepth(root->right);
        return  max(maxle,maxri)+1;
    }
};

int main()
{
	//****案例1**** 
	    /
        //      5      //
        //    /   \    //
        //   3    6    //
        //  / \    \   //
        // 2  4     8  //
        /
    TreeNode* root;
    root = new TreeNode(5);
    root->left = new TreeNode(3);
    root->right = new TreeNode(6);
    root->left->left= new TreeNode(2);
    root->left->right= new TreeNode(4);
    root->right->right= new TreeNode(8);

	cout<<"二叉树的最大深度为:"<<Solution().maxDepth(root)<<endl;
	return 0;
}

运行结果为:
在这里插入图片描述

完整的main函数的运行结果为:
在这里插入图片描述

以上所有代码均上传在我的github中github地址,后续会继续总结其他数据结构的基础算法实现。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值