[C++系列] 63. 二叉树的类模板实现及相关OJ

在这里插入图片描述

#pragma once
#include <stack>
#include <queue>

namespace yl {

template < class T >
class TreeNode
{
	T m_val;

	TreeNode<T> * m_left;
	TreeNode<T> * m_right;
public:
	TreeNode(const T &val) :
		m_val(val)
	{

	}

	template <class T>
	friend class Tree;
};

template <class T>
class Tree
{
	TreeNode<T> * m_root;

	// 递归建树
	static TreeNode<T> *  maketree(const T * val, const T & end, int &i)
	{
		if (val[i] == end)
		{
			i++;	// 跳过该位置
			return nullptr;
		}

		TreeNode<T> * root = new TreeNode<T>(val[i]);
		i++;

		root->m_left = maketree(val, end, i);
		root->m_right = maketree(val, end, i);

		return root;
	}
public:
	Tree() :
		m_root(nullptr)
	{

	}

	// 构造二叉树
	Tree(const T * val, const T & end)
	{
		int i = 0;
		m_root = maketree(val, end, i);
	}

	void pre_order()
	{
		TreeNode<T> * cur = m_root;
		stack<TreeNode<T> *> st;

		while (cur)
		{
			cout << cur->m_val << ' ';

			if (cur->m_right)
			{
				st.push(cur->m_right);
			}

			if (cur->m_left)
			{
				cur = cur->m_left;
			}
			else
			{
				if (st.empty())
				{
					cur = nullptr;
				}
				else
				{
					cur = st.top();
					st.pop();
				}
			}
		}
	}

	void in_order()
	{
		TreeNode<T> * cur = m_root;
		stack<TreeNode<T> *> st;

		while (cur || !st.empty())
		{
			for (; cur; cur = cur->m_left)
			{
				st.push(cur);
			}

			if (!st.empty())
			{
				cur = st.top();
				st.pop();
				cout << cur->m_val << ' ';

				cur = cur->m_right;
			}
		}
	}

	void post_order()
	{
		TreeNode<T> * cur = m_root;
		stack<TreeNode<T> *> st;
		stack<bool> tag;

		while (cur || !st.empty())
		{
			for (; cur; cur = cur->m_left)
			{
				st.push(cur);
				tag.push(false);
			}

			while (!st.empty() && tag.top())
			{
				cur = st.top();
				cout << cur->m_val << ' ';
				st.pop();
				tag.pop();

				cur = nullptr;
			}

			if (!st.empty())
			{
				tag.top() = true;
				cur = st.top();
				cur = cur->m_right;
			}
		}
	}
	
	// 二叉树的最近公共祖先
	TreeNode<T> * lowestCommonAncestor(TreeNode<T> * p, TreeNode<T> * q)
	{
		TreeNode<T> * cur = m_root;
		stack<TreeNode<T> *> st;
		stack<bool> tag;

		stack<TreeNode<T> *> res1;
		stack<TreeNode<T> *> res2;

		while (cur || !st.empty())
		{
			for (; cur; cur = cur->m_left)
			{
				st.push(cur);
				tag.push(false);
			}

			while (!st.empty() && tag.top())
			{
				cur = st.top();
				if (cur == p || cur == q)
				{
					if (res1.empty())
					{
						res1 = st;
					}
					else
					{
						res2 = st;
					}
				}
				st.pop();
				tag.pop();

				cur = nullptr;
			}

			if (!st.empty())
			{
				tag.top() = true;
				cur = st.top();
				cur = cur->m_right;
			}
		}

		if (res1.size() < res2.size())
		{
			swap(res1, res2);
		}

		int i = res1.size() - res2.size();

		for (; i > 0; i--)
		{
			res1.pop();
		}

		while (res1.top() != res2.top())
		{
			res1.pop();
			res2.pop();
		}

		return res1.top();
	}
	
	// 二叉树的最近公共祖先
	TreeNode<T> * lowestCommonAncestori(TreeNode<T> * p, TreeNode<T> * q)
	{
		TreeNode<T> * cur = m_root;
		stack<TreeNode<T> *> st;
		TreeNode<T> * tmp = nullptr;
		size_t stsize = 0;

		while (cur || !st.empty())
		{
			for (; cur; cur = cur->m_left)
			{
				st.push(cur);
			}

			if (!st.empty())
			{
				cur = st.top();

				if (stsize > st.size())
				{
					tmp = cur;
					stsize = st.size();
				}

				if (cur == p || cur == q)
				{
					if (!tmp)
					{
						tmp = cur;
						stsize = st.size();
					}
					else
					{
						return tmp;
					}
				}

				st.pop();

				cur = cur->m_right;
			}
		}
		return nullptr;
	}

	void test()
	{
		TreeNode<T> * t = lowestCommonAncestori(m_root->m_right->m_left->m_right, m_root->m_right);
		cout << t->m_val;
	}

	void level_order()
	{
		queue<TreeNode<T> *> qu;
		TreeNode<T> * tmp;

		qu.push(m_root);

		while (!qu.empty())
		{
			tmp = qu.front();
			cout << tmp->m_val << ' ';
			qu.pop();

			if (tmp->m_left)
			{
				qu.push(tmp->m_left);
			}

			if (tmp->m_right)
			{
				qu.push(tmp->m_right);
			}
		}
	}

	void everyline_level_order()
	{
		queue<TreeNode<T> *> qu;
		TreeNode<T> * tmp;
		int length = 1;

		qu.push(m_root);

		while (!qu.empty())
		{
			for (int i = 0; i < length; i++)
			{
				tmp = qu.front();
				cout << tmp->m_val << ' ';
				qu.pop();

				if (tmp->m_left)
				{
					qu.push(tmp->m_left);
				}

				if (tmp->m_right)
				{
					qu.push(tmp->m_right);
				}
			}
			cout << endl;
			length = qu.size();
		}
	}

	void max_level_order()
	{
		queue<TreeNode<T> *> qu;
		TreeNode<T> * tmp;
		int length = 1;
		T max;

		qu.push(m_root);

		while (!qu.empty())
		{
			max = qu.front()->m_val;
			for (int i = 0; i < length; i++)
			{
				tmp = qu.front();

				if (max < tmp->m_val)
				{
					max = tmp->m_val;
				}
				qu.pop();

				if (tmp->m_left)
				{
					qu.push(tmp->m_left);
				}

				if (tmp->m_right)
				{
					qu.push(tmp->m_right);
				}
			}
			cout << max << ' ';
			length = qu.size();
		}
	}

};

};
#include <iostream>
#include <algorithm>
#include "binaryTree.h"
using namespace std;

int main()
{
	//int arr[] = { 1, 2, -1, -1, 3, -1, -1 };
	//yl::Tree<int> tr2(arr, -1);

	//yl::Tree<char> tr("ABD##E##CFH##I##G##", '#');

	int arr[] = { 5, 8, 4, 12, -1, -1, 18, 17, -1, -1, 21, -1, -1, 9, -1, 7, -1, -1, 7, 6, -1, 5, 11, -1, -1, -1, 3, 4, -1, -1, 1, 14, -1, -1, -1 };
	yl::Tree<int> tr(arr, -1);
	/*
	tr.pre_order();
	cout << endl;
	tr.in_order();
	cout << endl;
	tr.post_order();
	cout << endl;
	//tr.test();
	tr.level_order();
	cout << endl;
	tr.everyline_level_order();
	*/

	tr.max_level_order();
	return 0;
}
发布了209 篇原创文章 · 获赞 42 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/yl_puyu/article/details/103421479