【DS】数据结构--二叉树实现

最近开始复习数据结构,感觉脑子不好使,特此记录一下,以便日后查看,也希望能给大家一些帮助!



类定义和一些函数接口:

template<class T>
struct BinaryTreeNode
{
	BinaryTreeNode(T data)
		:_data(data),
		_left(NULL),
		_right(NULL)
	{}
	BinaryTreeNode<T>* _left;
	BinaryTreeNode<T>* _right;
	T _data;
};
template<class T>
class BinaryTree
{
	typedef BinaryTreeNode<T> Node;
public:
	BinaryTree();
	BinaryTree(T* arr, size_t size, const T& value);
	//BinaryTree(const BinaryTree<T>& other);
	//BinaryTree<T>& operator=(const BinaryTree<T>& other);
	//~BinaryTree();
	//递归遍历
	void PreOrder();
	void InOrder();
	void PostOrder();
	
	//迭代遍历
	void PreOrder_NoR();
	void InOrder_NoR();
	void PostOrder_NoR();
	void LevelOrder();


	size_t Size();
	size_t Depth();
	size_t LeafSize();

下面时完整的代码:

#include <iostream>
#include <assert.h>
#include <queue>
#include <stack>
using namespace std;


template<class T>
struct BinaryTreeNode
{
	BinaryTreeNode(T data)
		:_data(data),
		_left(NULL),
		_right(NULL)
	{}
	BinaryTreeNode<T>* _left;
	BinaryTreeNode<T>* _right;
	T _data;
};
template<class T>
class BinaryTree
{
	typedef BinaryTreeNode<T> Node;
public:
	BinaryTree();
	BinaryTree(T* arr, size_t size, const T& value);
	BinaryTree(const BinaryTree<T>& other);
	//BinaryTree<T>& operator=(BinaryTree<T>& other);
	BinaryTree<T>& operator=(BinaryTree<T> other);
	~BinaryTree();
	//递归遍历
	void PreOrder();
	void InOrder();
	void PostOrder();
	
	//迭代遍历
	void PreOrder_NoR();
	void InOrder_NoR();
	void PostOrder_NoR();
	void LevelOrder();

	size_t Size();
	size_t Depth();
	size_t LeafSize();
protected:

	void _PreOrder(Node* root)
	{
		if (root== NULL)
		{
			return;
		}
		else
		{
			cout << root->_data << " ";
			_PreOrder(root->_left);
			_PreOrder(root->_right);
		}
	}
	void _InOrder(Node* root)
	{
		if (root == NULL)
		{
			return;
		}
		_InOrder(root->_left);
		cout << root->_data << " ";
		_InOrder(root->_right);
	}

	void _PostOrder(Node* root)
	{
		if (root == NULL)
		{
			return;
		}
		_PostOrder(root->_left);
		_PostOrder(root->_right);
		cout << root->_data << " ";
	}
	Node* CreateTree(T* arr, size_t size,size_t& index, const T& value)
	{
		Node* root = NULL;
		if (index <size && arr[index] != value)
		{
			root = new Node(arr[index]);
			root->_left = CreateTree(arr, size,++index, value);
			root->_right = CreateTree(arr, size,++index, value);
		}
		return root;
	}
	size_t _Size(Node* root)
	{
		if (root == NULL)
		{
			return 0;
		}
		return _Size(root->_left) + _Size(root->_right) + 1;
	}
	size_t _Depth(Node* root)
	{
		if (root == NULL)
		{
			return 0;
		}
		size_t left = _Depth(root->_left)+1;
		size_t right = _Depth(root->_right)+1;

		return left > right ? left : right;
	}

	size_t _LeafSize(Node* root)
	{
		if (root == NULL)
			return 0;
		if (root->_left == NULL &&root->_right == NULL)
		{
			return 1;
		}

		return _LeafSize(root->_left) + _LeafSize(root->_right);
	}
	Node* CopyTree(Node* root)
	{
		Node* Croot = NULL;
		if (NULL == root)
			return NULL;
		Croot = new Node(root->_data);
		Croot->_left = CopyTree(root->_left);
		Croot->_right = CopyTree(root->_right);

		return Croot;
	}
	void _destroy(Node* root)
	{
		if (root)
		{
			_destroy(root->_left);
			_destroy(root->_right);

			delete root;
			root = NULL;
		}
	}
protected:
	Node* _root;
};

template<class T>
BinaryTree<T>::BinaryTree()
{
	_root = NULL;
}

template<class T>
BinaryTree<T>::BinaryTree(T* arr, size_t size, const T& value)
{
	size_t index = 0;
	_root = CreateTree(arr, size,index, value);
}
template<class T>
BinaryTree<T>::~BinaryTree()
{
	_destroy(_root);
}
template<class T>
BinaryTree<T>::BinaryTree(const BinaryTree<T>& other)
{
	_root = CopyTree(other._root);
}

//方法一
//template<class T>
//BinaryTree<T>& BinaryTree<T>::operator=(BinaryTree<T>& other)
//{
//	if (this != &other)
//	{
//		this->~BinaryTree();
//	}
//	_root = CopyTree(other._root);
//	return *this;
//}

//方法二
template<class T>
BinaryTree<T>& BinaryTree<T>::operator=(BinaryTree<T> other)
{
	swap(_root, other._root);
	return *this;
}
template<class T>
void BinaryTree<T>::PreOrder()
{
	_PreOrder(_root);
	cout << endl;
}
template<class T>
void BinaryTree<T>::PreOrder_NoR()
{
	Node* cur = _root;
	stack<Node*> s;

	while (cur || !s.empty())
	{
		while (cur)
		{
			cout << cur->_data << " ";
			s.push(cur);
			cur = cur->_left;
		}

		if (!s.empty())
		{
			cur = s.top();
			s.pop();
			cur = cur->_right;
		}
	}
	cout << endl;
}
template<class T>
void BinaryTree<T>::InOrder()
{
	_InOrder(_root);
	cout << endl;
}


template<class T>
void BinaryTree<T>::InOrder_NoR()
{
	Node* cur = _root;
	stack<Node*> s;

	while (cur || !s.empty())
	{
		while (cur)
		{
			s.push(cur);
			cur = cur->_left;
		}
		Node* temp = s.top();
		s.pop();
		cout << temp->_data << " ";
		cur = temp->_right;
	}
	cout << endl;
}

template<class T>
void BinaryTree<T>::PostOrder_NoR()
{
//要保证根结点在左孩子和右孩子访问之后才能访问,  
//因此对于任一结点P,先将其入栈。如果P不存在左孩子和右孩子,则可以直接访问它;  
//或者P存在左孩子或者右孩子,但是其左孩子和右孩子都已被访问过了,则同样可以直接访问该结点。  
//若非上述两种情况,则将P的右孩子和左孩子依次入栈,这样就保证了每次取栈顶元素的时候,  
//左孩子在右孩子前面被访问,左孩子和右孩子都在根结点前面被访问。
	
	Node* cur = _root;
	Node* prev = NULL;
	stack<Node*> st;


	if (_root==NULL)
	{
		return;
	}
	st.push(cur);
	while (!st.empty())
	{
		cur = st.top();
		if ((cur->_left == NULL && cur->_right == NULL)\
			|| (prev != NULL) && (prev == cur->_left || prev == cur->_right))
		{//如果无左右子树,访问,或者左右子树已经访问过,也可以访问。
			cout << cur->_data << " ";
			st.pop();
			prev = cur;
		}
		else
		{
			if (cur->_right)
			{
				st.push(cur->_right);
			}
			if (cur->_left)
			{
				st.push(cur->_left);
			}
		}
		
	}
	cout << endl;
}

template<class T>
void BinaryTree<T>::PostOrder()
{
	_PostOrder(_root);
	cout << endl;
}

template<class T>
void BinaryTree<T>::LevelOrder()
{
	queue<Node*> qu;
	if (_root)
	{
		qu.push(_root);
	}
	while (!qu.empty())
	{
		Node* front = qu.front();
		qu.pop();
		cout << front->_data << " ";
		if (front->_left)
		{
			qu.push(front->_left);
		}
		if (front->_right)
		{
			qu.push(front->_right);
		}
	}
	cout << endl;
}


template<class T>
size_t BinaryTree<T>::Size()
{
	return _Size(_root);
}
/*void _size()
{
	gsize = 0;//每次必须初始化为0 ,否则会有叠加;
	_size(root);
	return gsize;
}

//定义一个gsize的全局变量,根据其作用域,遍历树,++gsize即可。
//存在的问题是每次必须初始化为0,否则会有bug;两个对象共享一个全局变量的bug。

//这种全局或者静态的全局变量存在线程安全的问题,我们可以在栈上设置一个共享的变量,用引用, int &size。
//size在递归的过程中是独立存在的;
size_t _Size(Node* root)
{
	if (root == NULL)
	{
		return 0;
	}
	gsize++;
	_Size(root->_left);
	_Size(root->_right);

}*/
template<class T>
size_t BinaryTree<T>::Depth()
{
	return _Depth(_root);
}

template<class T>
size_t BinaryTree<T>::LeafSize()
{
	return _LeafSize(_root);
}


下面是测试代码:

void test()
{
	int arr[10] = {1,2,3,'#','#',4,'#','#',5,6};
	BinaryTree<int> t1(arr, 10, '#');

	cout << "递归先序遍历" << endl;
	t1.PreOrder();

	cout << "递归中序遍历" << endl;
	t1.InOrder();

	cout << "递归后序遍历" << endl;
	t1.PostOrder();

	cout << "非递归先序遍历" << endl;
	t1.PreOrder_NoR();

	cout << "非递归中序遍历" << endl;
	t1.InOrder_NoR();

	cout << "非递归后序遍历" << endl;
	t1.PostOrder_NoR();
	cout << "层次遍历" << endl;
	t1.LevelOrder();

	cout<<"Size == "<<t1.Size()<<endl;
	cout << "Depth == " << t1.Depth() << endl;
	cout << "LeafSize == " << t1.LeafSize() << endl;
}
int main()
{
	test();
	return 0;
}
运行结果如图所示:



你可能感兴趣的:(【DS】数据结构--二叉树实现)