二叉树的遍历算法实现、以及所有简单操作

二叉树的遍历分为先序遍历,中序遍历,后序遍历,层序遍历

先序遍历根节点->左子树->右子树

       递归思想:判断根节点是否为空,若不为空则打印根节点数据,然后调用函数取根节点左子树的数据,然后再调用函数取右子树的数据。

      递归实现:

void PrevOrder() //前序遍历
	{
		cout << "前序遍历为:";
		_PrevOrder(_root);
		cout << endl;
	}

void _PrevOrder(Node* root)  //根->左子树->右子树
	{
		if (root == NULL)
			return;

		cout << root->_value << " ";
		_PrevOrder(root->_left);
		_PrevOrder(root->_right);
		
	}

非递归思想:定义一个栈q,定义一个节点p指针指向根节点;将p压入栈后,取该节点的值,并且让p=p的左子树同时压入q栈中,直到左子树为空,这个时候取栈的栈顶元素,然后删除栈顶元素,并将p节点设置为根节点的右子树节点。让其再重复其上述操作。

简单流程图:



非递归实现:

	void PrevOrder_NonR()
	{
		stack<Node*> q;
		Node* p = _root;
		while (p != NULL || !q.empty())
		{
			while (p != NULL)
			{
				q.push(p);
				cout << p->_value << " ";
				p = p->_left;
			}
				Node* node = q.top();
				q.pop();
				p = node->_right;
		}
		cout << endl;
	}
中序遍历:

递归实现:

void InOrder()//中序遍历
	{
		cout << "中序遍历为:";
		_InOrder(_root);
		cout << endl;
	}

	void _InOrder(Node* root)//左子树->根节点->右子树
	{
		if (root == NULL)
			return;

		_InOrder(root->_left);
		cout << root->_value << " ";
		_InOrder(root->_right);
	}
非递归想法: 定义一个栈,定义一个节点p指针指向根节点,然后将这个树的所有左子树压入栈中,然后取其栈顶的元素,然后将栈顶pop掉,让p=栈顶节点的右子树,然后重复上面的步骤。

非递归实现:

void InOrder_NonR()
	{
		stack<Node*> q;
		Node* p = _root;
		while (p != NULL || !q.empty())
		{
			while (p != NULL)
			{
				q.push(p);
				p = p->_left;
			}
	
				Node* node = q.top();
				cout << node->_value << " ";
				q.pop();
				p = node->_right;
		}
		cout << endl;
	}
后序遍历:

递归实现:

void PostOrder()//后序遍历
	{
		cout << "后序遍历为:";
		_PostOrder(_root);
		cout << endl;
	}

void _PostOrder(Node* root)//左子树->右子树->根节点
	{
		if (root == NULL)
			return;

		_PostOrder(root->_left);
		_PostOrder(root->_right);
		cout << root->_value << " ";
	}

非递归实现:定义一个栈,定义一个节点指针p指向树的根节点;再定义一个节点指针prev指向上次所访问的指针,如果栈不为空或者节点p不等于NULL;则将该树的所有左子树压入栈中,然后取栈顶元素,如果这个栈顶元素的右子树为空或者是上次访问的指针,那么说明这个栈顶元素的左右子树已经遍历了,那么就打印该元素节点的数据, 如果这个栈顶元素的右子树不为空或者是不是上次访问的指针,那么就让p指向栈顶元素的右子树,然后重复上述操作。

void PostOrder_NonR()
	{
		stack<Node*> s;
		Node* p = _root;
		Node* prev = NULL;
		while (p != NULL || !s.empty())
		{
			while (p != NULL)
			{
				s.push(p);
				p = p->_left;
			}
			Node* node = s.top();
			if (node->_right == NULL || prev == node->_right)
			{
				cout <<node->_value << " ";
				s.pop();
				prev = node;
			}
			else
			{
				p = node->_right;
			}
		}
		cout << endl;
	}

层序遍历:

	void LevelOrder() //层序遍历
	{
		cout << "层序遍历为:";
		if (_root != NULL)
		{
			queue<Node*> q;
			q.push(_root);

			while (!q.empty())
			{
				Node* front = q.front();
				cout << front->_value << " ";
				q.pop();

				if (front->_left)
					q.push(front->_left);
				if (front->_right)
					q.push(front->_right);
			}
		}
		cout << endl;
	}


计算深度算法:

size_t Depth() //计算树的深度
	{
		return _Depth(_root);
	}
size_t _Depth(Node* root)
	{
		if (root == NULL)
			return 0;
		size_t left = _Depth(root->_left);
		size_t right = _Depth(root->_right);
		if (left > right)
		{
			return (left + 1);
		}
		return (right + 1);
	}

计算节点算法:

size_t Size() //统计结点数量
	{
		return _Size(_root);
	}
size_t _Size(Node* root)
	{
		if (root == NULL)
			return 0;

		return _Size(root->_left) + _Size(root->_right) + 1;
	}

计算叶节点算法:

size_t LeafSize() //统计叶结点的数量
	{
		return _LeafSize(_root);
	}
size_t _LeafSize(Node* root)
	{
		size_t count = 0;
		if (root == NULL)
			return 0;

		if (root->_left == NULL && root->_right == NULL)
			return 1;
		else
			return _LeafSize(root->_left) + _LeafSize(root->_right);
	}

计算满结点算法:

size_t FullSize()//计算满二叉树的结点个数
	{
		return _FullSize(_root);
	}
size_t _FullSize(Node* root)
	{
		if (root == NULL)
			return 0;
		else if (root->_left == NULL && root->_right == NULL)
			return 0;
		else if (root->_left != NULL && root->_right == NULL)
			return _FullSize(root->_left);
		else if (root->_left == NULL && root->_right != NULL)
			return _FullSize(root->_right);
		else if (root->_left != NULL && root->_right != NULL)
			return _FullSize(root->_left) + _FullSize(root->_right) + 1;
	}

寻找节点算法:

Node* Find(const size_t& x)
	{
		return _Find(_root,x);
	}
Node* _Find(Node* root,const size_t& x )
	{
		if (root == NULL)
			reutrn NULL;

		if (root->_value == x)
			return root;

		Node* ret = _Find(root->_left, x);
		if (ret != NULL)
			return ret;

		return _Find(root->_right, x);
	}


求K层节点数算法:

size_t GetKleve(size_t K) //获取K层结点个数
	{
		return _GetKleve(_root, K);
	}
size_t _GetKleve(Node* root, size_t K)
	{
		assert(K > 0);
		if (root == NULL)
			return 0;
		if (K == 1)
			return 1;
		return _GetKleve(root->_left, K - 1) + _GetKleve(root->_right, K - 1);
	}

全部代码实现:

#include<iostream>
using namespace std;
#include<queue>
#include<stack>
#include<assert.h>
template<class T>
struct binarytreeNode
{
	T _value;
	binarytreeNode<T>* _left;  //左子树
	binarytreeNode<T>* _right;  //右子树
	binarytreeNode(const T& value)
		:_value(value)
		, _left(NULL)
		, _right(NULL)
	{}
};

template<class T>
class binarytree
{
	typedef binarytreeNode<T> Node;
public:
	binarytree()
		:_root(NULL)
	{}
	binarytree(T* arr, size_t n, const T& invalid = T())
	{
		size_t index = 0;
		_root = _Greatree(arr, n, invalid, index);
	}
	~binarytree()
	{
		_Destory(_root);
	}
	binarytree(const binarytree<T>& t)
	{
		_root = Copy(t._root);
	}
	
	binarytree<T>& operator=(const binarytree<T>& t)
	{
		if (this != t)
		{
			Node* newNode = Copy(t._root);
			_Destory(_root);
			_root = newNode;
		}
		return *this;
	}
	void PrevOrder() //前序遍历
	{
		cout << "前序遍历为:";
		_PrevOrder(_root);
		cout << endl;
	}
	void PrevOrder_NonR()
	{
		stack<Node*> q;
		Node* p = _root;
		while (p != NULL || !q.empty())
		{
			while (p != NULL)
			{
				q.push(p);
				cout << p->_value << " ";
				p = p->_left;
			}
				Node* node = q.top();
				q.pop();
				p = node->_right;
		}
		cout << endl;
	}

	void InOrder()//中序遍历
	{
		cout << "中序遍历为:";
		_InOrder(_root);
		cout << endl;
	}

	void InOrder_NonR()
	{
		stack<Node*> q;
		Node* p = _root;
		while (p != NULL || !q.empty())
		{
			while (p != NULL)
			{
				q.push(p);
				p = p->_left;
			}
	
				Node* node = q.top();
				cout << node->_value << " ";
				q.pop();
				p = node->_right;
		}
		cout << endl;
	}
	void PostOrder()//后序遍历
	{
		cout << "后序遍历为:";
		_PostOrder(_root);
		cout << endl;
	}
	void PostOrder_NonR()
	{
		stack<Node*> s;
		Node* p = _root;
		Node* prev = NULL;
		while (p != NULL || !s.empty())
		{
			while (p != NULL)
			{
				s.push(p);
				p = p->_left;
			}
			Node* node = s.top();
			if (node->_right == NULL || prev == node->_right)
			{
				cout <<node->_value << " ";
				s.pop();
				prev = node;
			}
			else
			{
				p = node->_right;
			}
		}
		cout << endl;
	}
	void LevelOrder() //层序遍历
	{
		cout << "层序遍历为:";
		if (_root != NULL)
		{
			queue<Node*> q;
			q.push(_root);

			while (!q.empty())
			{
				Node* front = q.front();
				cout << front->_value << " ";
				q.pop();

				if (front->_left)
					q.push(front->_left);
				if (front->_right)
					q.push(front->_right);
			}
		}
		cout << endl;
	}

	size_t Size() //统计结点数量
	{
		return _Size(_root);
	}

	size_t Depth() //计算树的深度
	{
		return _Depth(_root);
	}

	size_t LeafSize() //统计叶结点的数量
	{
		return _LeafSize(_root);
	}

	size_t FullSize()//计算满二叉树的结点个数
	{
		return _FullSize(_root);
	}

	size_t GetKleve(size_t K) //获取K层结点个数
	{
		return _GetKleve(_root, K);
	}
	Node* Find(const size_t& x)
	{
		return _Find(_root,x);
	}

protected:
	void _PrevOrder(Node* root)  //根->左子树->右子树
	{
		if (root == NULL)
			return;

		cout << root->_value << " ";
		_PrevOrder(root->_left);
		_PrevOrder(root->_right);
		
	}
	void _InOrder(Node* root)//左子树->根节点->右子树
	{
		if (root == NULL)
			return;

		_InOrder(root->_left);
		cout << root->_value << " ";
		_InOrder(root->_right);
	}
	void _PostOrder(Node* root)//左子树->右子树->根节点
	{
		if (root == NULL)
			return;

		_PostOrder(root->_left);
		_PostOrder(root->_right);
		cout << root->_value << " ";
	}
	size_t _Size(Node* root)
	{
		if (root == NULL)
			return 0;

		return _Size(root->_left) + _Size(root->_right) + 1;
	}

	size_t _LeafSize(Node* root)
	{
		size_t count = 0;
		if (root == NULL)
			return 0;

		if (root->_left == NULL && root->_right == NULL)
			return 1;
		else
			return _LeafSize(root->_left) + _LeafSize(root->_right);
	}

	size_t _FullSize(Node* root)
	{
		if (root == NULL)
			return 0;
		else if (root->_left == NULL && root->_right == NULL)
			return 0;
		else if (root->_left != NULL && root->_right == NULL)
			return _FullSize(root->_left);
		else if (root->_left == NULL && root->_right != NULL)
			return _FullSize(root->_right);
		else if (root->_left != NULL && root->_right != NULL)
			return _FullSize(root->_left) + _FullSize(root->_right) + 1;
	}
	size_t _GetKleve(Node* root, size_t K)
	{
		assert(K > 0);
		if (root == NULL)
			return 0;
		if (K == 1)
			return 1;
		return _GetKleve(root->_left, K - 1) + _GetKleve(root->_right, K - 1);
	}

	size_t _Depth(Node* root)
	{
		if (root == NULL)
			return 0;
		size_t left = _Depth(root->_left);
		size_t right = _Depth(root->_right);
		if (left > right)
		{
			return (left + 1);
		}
		return (right + 1);
	}

	Node* _Find(Node* root,const size_t& x )
	{
		if (root == NULL)
			reutrn NULL;

		if (root->_value == x)
			return root;

		Node* ret = _Find(root->_left, x);
		if (ret != NULL)
			return ret;

		return _Find(root->_right, x);
	}
	Node* _Greatree(T* arr, size_t n,const T& invalid , size_t& index)
	{
		Node * node = NULL;
		if (arr[index] != invalid && index < n)
		{
			node = new Node(arr[index]);
			node->_left = _Greatree(arr, n, invalid, ++index);
			node->_right = _Greatree(arr, n, invalid, ++index);
		}

	  return node;
	}
	Node* Copy(Node* root)
	{
		if (root == NULL)
			return NULL;
		Node* newNode = new Node(root->_value);
		newNode->_left = Copy(root->_left);
		newNode->_right = Copy(root->_right);

		return newNode;
	}
	void _Destory(Node* root)
	{
		if (root == NULL)
			return;

		_Destory(root->_left); 
		_Destory(root->_right);

		delete root;
	}
private:
	Node* _root;
};

测试用例:
void Text()
{
	int array[10] = { 1, 2, 3, '#', '#', 4, '#', '#', 5, 6 };
	binarytree<int> a(array, sizeof(array) / sizeof(array[0]), '#');
	a.PrevOrder();
	a.PrevOrder_NonR();
	a.InOrder();
	a.InOrder_NonR();
	a.PostOrder();
	a.PostOrder_NonR();
	a.LevelOrder();
	cout << a.Size() << endl;
	cout << a.LeafSize() << endl;
	cout << a.Depth() << endl;
	cout << a.FullSize() << endl;

	cout << a.GetKleve(1) << endl;
	cout << a.GetKleve(2) << endl;
	cout << a.GetKleve(3) << endl;
	binarytree<int> b(a);
}







评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值