二叉樹(一)

樹是n(n>=0)個有限個數據的元素集合,形狀像一顆倒過來的樹。


wKiom1cz_wejdM9BAAA8rH_zdpQ806.png1是樹,無環路。2不是樹,有環路。


二叉樹:二叉樹是一棵特殊的樹,二叉樹每個節點最多有兩個孩子結點,分別稱爲左孩子和右孩子。

滿二叉樹:高度爲N的滿二叉樹有2^N - 1個節點的二叉樹。

完全二叉樹: 若設二叉樹的深度爲h,除第 h 層外,其它各層 (1~h-1) 的結點數都達到最大個數,第 h 層所有的結點都連續集中在最左邊,這就是完全二叉樹

wKioL1c0ARexYFhgAAA6C1j3UC8306.png

樹的遍歷

舉例:

wKiom1c0ARXxZdJfAAAaHK-Vz9o319.png

前序遍歷(先根遍歷):1,先訪問根節點;2,前序訪問左子樹;3,前序訪問右子樹; 【1 2 3 4 5 6】

中序遍歷:  1,中序訪問左子樹;2,訪問根節點;3,中序訪問右子樹;                  【3 2 4 1 6 5】

後序遍歷(後根遍歷),1,後序訪問左子樹;2,後序訪問右子樹;3,訪問根節點;    【3 4 2 6 5 1】

層序遍歷: 一層層節點依次遍歷。                                                                         【1 2 5 3 4 6】


spacer.gif樹的鏈表結構

wKiom1c0AVPSgdz5AABiBERIyKY015.png樹的構造及代碼實現

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

	BinaryTree(const T* str, size_t size,const T& invalid)
	{
		size_t index = 0;
		_root = _CreateTree(str, size,index, invalid);
	}

	BinaryTree(const BinaryTree<T>& b)
	{
		_root = _Copy(b._root);
	}

	BinaryTree<T>& operator=(BinaryTree<T> b)
	{
		swap(_root, b._root);
		return *this;
	}

	~BinaryTree()
	{
		_Destory(_root);
	}	

protected:
	BinaryTreeNode<T>* _CreateTree(const T* str, size_t size, size_t& index, const T& invalid)
	{
	        //傳引用是爲了防止回退
		BinaryTreeNode<T>* root = NULL;
		if ((index < size) && (str[index] != invalid))
		{
			root = new BinaryTreeNode<T>(str[index]);
			//先構建左子樹
			root->_left = _CreateTree(str, size, ++index, invalid);
			//再構建右子樹
			root->_right = _CreateTree(str, size, ++index, invalid);
		}
		return root;
	}

	BinaryTreeNode<T>* _Copy(const BinaryTreeNode<T>* root)
	{
		if (root)
		{
	      BinaryTreeNode<T>* newRoot = new BinaryTreeNode<T>(root->_data);
		  newRoot->_left = _Copy(root->_left);
		  newRoot->_right = _Copy(root->_right);
		  return newRoot;
		}
		return NULL;	
	}

	void _Destory(BinaryTreeNode<T>* root)
	{
		BinaryTreeNode<T>* cur = root;
		if (root)
		{
			_Destory(root->_left);
			_Destory(root->_right);
			delete cur;
			cur = NULL;
			root = NULL;
		}
		return;
	}
protected:
	BinaryTreeNode<T>* _root;
};


樹的遞歸遍歷

public:
	void PrevOrder()  //前序遞歸
	{
		_PrevOrder(_root);
		cout << endl;
	}

	void InOrder()    //中序遞歸
	{
		_InOrder(_root);
		cout << endl;
	}

	void PostOrder()   //後序遞歸
	{
		_PostOrder(_root);
		cout << endl;
	}
	
	void LevelOrder()   //層序遞歸
	{
		_LevelOrder(_root);
	}
	
	protected:
	void _PrevOrder(const BinaryTreeNode<T>* root)
	{
		if (root == NULL)
		{
			return;
		}
		cout << root->_data << " ";
		_PrevOrder(root->_left);
		_PrevOrder(root->_right);
	}

	void _InOrder(const BinaryTreeNode<T>* root)
	{
		if (root == NULL)
		{
			return;
	    }
		_InOrder(root->_left);
		cout << root->_data << " ";
		_InOrder(root->_right);
		return;
	}

	void _PostOrder(const BinaryTreeNode<T>* root)
	{
		if (root == NULL)
		{
			return;
		}
		_PostOrder(root->_left);
		_PostOrder(root->_right);
		cout << root->_data << " ";
	}	
	
	void _LevelOrder(BinaryTreeNode<T>* root)
	{
		queue<BinaryTreeNode<T>*> q;
		q.push(root);
		while (0 < q.size())
		{
			BinaryTreeNode<T>* tmp = q.front();
			cout << tmp->_data << " ";
			q.pop();
			if (tmp->_left != NULL)
			{
				q.push(tmp->_left);
			}
			if (tmp->_right != NULL)
			{
				q.push(tmp->_right);
			}
		}
	}

樹的非遞歸遍歷

void PrevOrder_NonR()   //非遞歸前序
	{
		stack<BinaryTreeNode<T>* > v1;
		v1.push(_root);
		BinaryTreeNode<T>* cur = _root;
		cout << v1.top()->_data << " ";
		while (!v1.empty())
		{
			v1.pop();
			if (cur->_right)
			{
				v1.push(cur->_right);
			}
			if (cur->_left)
			{
				v1.push(cur->_left);
			}
			if (v1.size() == 0)
			{
				return;
			}
			cout << v1.top()->_data << " ";
			cur = v1.top();	
		}
	}

	void InOrder_NonR()   //非遞歸中序
	{
		stack<BinaryTreeNode<T>* > v2;
		BinaryTreeNode<T>* cur = _root;
		while (cur||!v2.empty())
		{
			while (cur)
			{
				v2.push(cur);
				cur = cur->_left;
			}

			cout << v2.top()->_data << " ";
			BinaryTreeNode<T>* top = v2.top();
			v2.pop();
			cur = top->_right;
		}
	}

	void PostOrder_NonR()     //非遞歸後序
	{
		BinaryTreeNode<T>* cur = _root;
		BinaryTreeNode<T>* prev = NULL;
		stack<BinaryTreeNode<T>* > s;
		while (cur || !s.empty())
		{
			while (cur)
			{
				s.push(cur);
				cur = cur->_left;
			}
			BinaryTreeNode<T>* top = s.top();
			if (top->_right == NULL || top->_right == prev)
			{
				cout << top->_data << " ";
				s.pop();
				prev = top;
			}
			else
			{
				cur = top->_right;
			}
		}
	}

樹的大小,深度....

       size_t Size()   //樹的大小
	{
		size_t size = _Size(_root);
		return size;
	}

	size_t Depth()   //樹的深度
	{
		size_t dep = _Depth(_root);
		return dep;
	}

	size_t LeafSize()    //葉子節點的個數
	{
		size_t count = _LeafSize(_root);
		return count;
	}

	BinaryTreeNode<T>* Find(const T& d)    //尋找結點
	{
		return _Find(_root, d);
	}

	//第K層有多少個結點
	/*size_t GetKLevel(const size_t& k)
	{
		return _GetKLevel(_root, k);
	}*/

	size_t GetKLevel(const size_t& k)
	{
	
		size_t level = 1;
		_GetKLevel(_root, 1evel, k, size);
		return size;
	}
	
	size_t _Size(const BinaryTreeNode<T>* root)
	{
		size_t size = 1;
		if (root==NULL)
		{
			return 0;
		}
		size += _Size(root->_left);
		size += _Size(root->_right);
		return size;
	}

	size_t _Depth(const BinaryTreeNode<T>* root)
	{
		size_t dep1 = 1;
		size_t dep2 = 1;
		if (root == NULL)
		{
			return 0;
		}
		dep1 += _Depth(root->_left);
		dep2 += _Depth(root->_right);
		if (dep1 > dep2)
		{
			return dep1;
		}
		else
		{
			return dep2;
		}
	}

	size_t _LeafSize(const BinaryTreeNode<T>* root)
	{
		size_t count = 0;
		if (root == NULL)
		{
			return 0;
		}
		if ((root->_left == NULL) && (root->_right == NULL))
		{
			return 1;
		}
		count += _LeafSize(root->_left);
		count += _LeafSize(root->_right);
		return count;
	}

	BinaryTreeNode<T>* _Find(BinaryTreeNode<T>* root, const T& d)
	{
		if (root == NULL)
		{
			return NULL;
		}
		if (root->_data == d)
		{
			return root;
		}
		BinaryTreeNode<T>* ret = _Find(root->_left, d);
		if (ret)
		{
			return ret;
		}
		return _Find(root->_right, d);
	}

	/*size_t _GetKLevel(BinaryTreeNode<T>* root, size_t k)
	{
		if (root == NULL)
		{
			return 0;
		}
		if (k == 1)
		{
			return 1;
		}
		return _GetKLevel(root->_left, k - 1) + _GetKLevel(root->_right, k - 1);
	}*/

	void _GetKLevel(BinaryTreeNode<T>* root, size_t level, size_t k, size_t& size)
	{
		if (root == NULL)
		{
			return;
		}
		if (k == level)
		{
			size++;
			return;
		}
		_GetKLevel(root->_left, level + 1, k, size);
		_GetKLevel(root->_right, level + 1, k, size);
	}

下一篇會給大家介紹樹的線索化,寫的不好的請多多指教哦哦哦哦~j_0002.gif

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