【C++】 二叉樹的基本知識及其遍歷

二叉樹:每個節點最多兩個孩子節點。

二叉樹的結構:         struct TreeNode

                      {  

                          DataType _value;     //節點值

                          TreeNode*  _left;    //左孩子

                          TreeNode*  _ridht;   //右孩子

                      };

二叉樹的基礎:        構造、拷貝構造、析構、賦值運算符的重載

二叉樹的知識點:      高度、節點的個數、子節點的個數

二叉樹的遍歷:        前序、中序、後序遍歷(遞歸及非遞歸)

遍歷順序:            前序——根左右          中序——左根右          後序——左右根

注意: 遞歸遍歷時,應該注意不要出現棧溢出現象。

      因爲++index返回對象,index++返回臨時變量,所以傳引用做參數時有++index。

#pragma once

#include<queue>
#include<stack>

//二叉樹的結構
template<class T>
struct BinaryTreeNode
{
	BinaryTreeNode<T>* _left;
	BinaryTreeNode<T>* _right;
	T _data;
	//構造函數
	BinaryTreeNode(const T& x)
		:_left(NULL)
		, _right(NULL)
		, _data(x)
	{}
};
template<class T>
class BinaryTree
{
	typedef BinaryTreeNode<T> Node;  

public:
	//構造
	BinaryTree()
		:_root(NULL)
	{}
	// a--樹的節點前序遍歷的數組  size--數組中元素個數  invaild--無效值即節點爲空
	BinaryTree(const T* a,size_t size,const T& invalid)
	{
		size_t index = 0;
		_root = _CreateTree(a, size,invalid,index);
	}
	//析構
	~BinaryTree()
	{
		_Destory(_root);
		_root = NULL;
	}
	//拷貝  
	BinaryTree(const BinaryTree<T>& t)
	{
		_root = _Copy(t._root);
	}
    //賦值重載(傳統)
	//BinaryTree<T>& operator=(const BinaryTree<T>& t)
	//{
	//	if (this != &t)
	//	{
	//		Node* tmp = _Copy(t._root);
	//		_Destory(_root);
	//		_root = tmp;
	//	}
	//	return *this;
	//}
	//賦值重載(現代)
	BinaryTree<T>& operator=(BinaryTree<T> t)
	{
		swap(_root, t._root);
		return *this;
	}

	T& operator->()
	{
		return _root;
	}

public:
	void PrevOrder()//前序
	{
		_PrevOrder(_root);
		cout << endl;
	}
	void InOrder()//中序
	{
		_InOrder(_root);
		cout << endl;
	}
	void PostOrder()//後序
	{
		_PostOrder(_root);
		cout << endl;
	}

	size_t Size()  //節點個數
	{
		return _Size(_root);
	}
	size_t Depth()  //樹的深度
	{
		return _Depth(_root);
	}
	size_t LeafSize()  //葉子節點個數
	{
		return _LeafSize(_root);
	}
	
	//層次遍歷
	void LevelOrder()
	{
		queue<Node*> q;
		if (_root)
		{
			q.push(_root);
		}
		while (!q.empty())
		{
			Node* front = q.front();
			cout << front->_data << " ";
			q.pop();

			if (front->_left)
			{
				q.push(front->_left);
			}
			if (front->_right)
			{
				q.push(front->_right);
			}
		}
		cout << endl;
	}
public:
	//非遞歸的前中後序遍歷(棧)
	void PrevOrder_NonR()
	{
		stack<Node*> s;
		if (_root)
			s.push(_root);
		while (!s.empty())
		{
			Node* top = s.top();
			cout << top->_data << " ";
			s.pop();
			//棧後進先出  ,所以 右先進,左先出
			if (top->_right)
				s.push(top->_right);
			if (top->_left)
				s.push(top->_left);
		}
		cout << endl;
	}
	void InOrder_NonR()
	{
		//壓左樹
		//取出一個節點即它的左路走完了,在訪問右樹(看作子問題)
		stack<Node*> s;
		Node* cur = _root;
		while (cur || !s.empty())
		{
			//壓樹的左路節點直至最左段節點
			while (cur)
			{
				s.push(cur);
				cur = cur->_left;
			}

			if (!s.empty())
			{
				Node* top = s.top();
				s.pop();
				cout << top->_data << " ";
				cur=top->_right;
			}
		}
		cout << endl;

	}

	void PostOrder_NonR()
	{
		Node* prev = NULL;
		Node* cur = _root;
		stack<Node*> s;
		while (cur || !s.empty())
		{
			//壓樹的左路節點直至最左段節點
			while (cur)
			{
				s.push(cur);
				cur = cur->_left;
			}

			Node* top = s.top();
			if (top->_right == NULL || top->_right == prev)
			{
				cout << top->_data << " ";
				s.pop();
				prev = top;
			}
			else
			{
				cur = top->_right;
			}
		}
		cout << endl;
	}


protected:
        //注意 此處index要用引用傳參
	Node* _CreateTree(const T* a, size_t size, const T& invalid, size_t& index) 
	{
		Node* root = NULL;
		if ((index < size) && (a[index] != invalid))
		{
			root = new Node(a[index]);
		
                        //注意下面只能用++index。此處傳的是引用 
                       //因爲++index返回對象,index++返回臨時變量。
			root->_left = _CreateTree(a, size, invalid, ++index);
			root->_right = _CreateTree(a, size, invalid, ++index);
                 }
		return root;
	}

	void _Destory(Node* root)
	{
		if (root == NULL)
			return;
		_Destroy(root->_left);
		_Destroy(root->_right);
		delete root;
	}
	Node* _Copy(Node* root)
	{
		if (root == NULL)
			return NULL;
		NOde* newRoot = new Node(root->_data);
		newRoot->_left = _Copy(root->_left);
		newRoot->_right = _Copy(root->_right);
		return newRoot;
	}
        //////////////
	void _PrevOrder(Node* root)
	{
		if (root == NULL)
			return;

		cout << root->_data << " ";
		_PrevOrder(root->_left);
		_PrevOrder(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 << " ";
	}

	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 LeftDepth = _Depth(root->_left);
		size_t RightDepth = _Depth(root->_right);

		return (LeftDepth > RightDepth) ? (LeftDepth + 1) : (RightDepth + 1);
	}

	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));
	}
private:
	Node *_root;
};


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章