BinaryTree

 二叉樹是一個比較重要的數據結構,這篇文章將基於linux下實現BinaryTree


 一.進入工作目錄,我自己在工作目錄下建了一個DataStruct的目錄。

 $touch BinaryTree.cpp 的文件

 $vim BinaryTree.cpp 


wKiom1dEgavAyOF_AAAkKfdqRTU485.png


 二.二叉樹

  1).二叉樹的建立 -- 遞歸建立


wKioL1dEgznTjs8xAAAnsZo0mMk827.png


 需要注意的點

  a.index爲數組下標索引,因爲是遞歸建立,所以必須傳引用。

  b.invaild爲無效數值,可以終止數的向下生長。

 2).二叉樹的先序遍歷

wKioL1dEhA3S4G71AAAfc59h28M282.png

  a.先序遍歷根節點,再遍歷左子樹,後遍歷右子樹。

 3).二叉樹的中序遍歷

wKioL1dEhPSDJ2E1AAAfNG5wDZ8250.png

a.先序遍歷左子樹,再遍歷根節點,後遍歷右子樹。

 4).二叉樹的後序遍歷

wKioL1dEhTmxk37JAAAf-nZYNFQ460.png

a.先序遍歷左子樹,再遍歷右子樹,後遍歷根節點。

 5).二叉樹的層序遍歷

wKioL1dEhaezWG-BAAA3ZC74P34777.png


a.借用隊列先進先出的特性,先壓根節點,之後訪問根節點,pop根節點,壓入左右子數,以此訪問。


 三.測試用例

wKioL1dEhmjihkQjAAAfFbANyHU133.png


wKiom1dEhbbiN9r0AABYigy2Aro631.png


$g++ -o BinaryTree BinaryTree.cpp -g (-g 是加入調試信息,方便gdb調試)

$./BinaryTree


結果

wKioL1dEhzHjGanyAAAZ78xiBrM228.png


附件:


代碼:

#pragma once
#include<iostream>
using namespace std;
#include<queue>


template<class T>
struct BinaryTreeNode
{
	BinaryTreeNode(const T& x)
	:_data(x)
	, _left(NULL)
	, _right(NULL)
	{}


	T _data;
	BinaryTreeNode<T>* _left;
	BinaryTreeNode<T>* _right;
};

template<class T>
class BinaryTree
{
	typedef BinaryTreeNode<T> Node;
public:
	BinaryTree()
		:_root(NULL)
	{}

	BinaryTree(const T* a, size_t size, const T& invaild)
	{
		size_t index = 0;
		_root = _BinaryTree(a, size, index, invaild);
	}

	~BinaryTree()
	{}

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

	void prevOrder()   //前序遍歷
	{
		_prevOrder(_root);
		cout << endl;
	}

	void inOrder()     //中序遍歷
	{
		_inOrder(_root);
		cout << endl;
	}

	void nextOrder()    //後序遍歷
	{
		_nextOrder(_root);
		cout << endl;

	}

	void levelOrder()
	{
		_levelOrder(_root);
	}

	size_t size()
	{
		return _size(_root);
	}

	size_t Depth()
	{
		return _Depth(_root);
	}

	size_t leafsize()
	{
		return _leafsize(_root);
	}

	size_t GetKLevel(int k)
	{
		return _GetKLevel(int k);
	}

protected:

	void _Destroy(Node* root)
	{
		if (root == NULL)
		{
			return;
		}
		//--------------------------------------------------
		_Destroy(root->_left);
		_Destroy(root->_right);

		_Destroy 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;
	}


	Node* _BinaryTree(const T* a, size_t size, size_t& index, const T& invaild)    //必須要給index加引用
	{
		Node* root = NULL;
		if (index < size && a[index] != invaild)
		{
			root = new Node(a[index]);
			root->_left = _BinaryTree(a, size, ++index, invaild);
			root->_right = _BinaryTree(a, size, ++index, invaild);
		}
		return root;
	}
	

	void _prevOrder(Node* root)
	{
		//Node* cur = 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 _nextOrder(Node* root)
	{
		if (root == NULL)
		{
			return;
		}
		_nextOrder(root->_left);
		_nextOrder(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;
	//	}
	//	return _Depth(root->_left) > _Depth(root->_right) ? _Depth(root->_left)+1 : _Depth(root->_right)+1;   //效率太低
	//}

	size_t _Depth(Node* root)
	{
		if (root == NULL)
		{
			return 0;
		}
		int leftdepth = _Depth(root->_left);   //---------------------------------
		int rightdepth = _Depth(root->_right);

		return leftdepth > rightdepth ? leftdepth+1 : rightdepth+1;
	}

	size_t _leafsize(Node* root)
	{
		static size_t size = 0;
		if (root == NULL)
		{
			return 0;
		}

		if (root->_left == NULL && root->_right == NULL)
		{
			++size;
			return size;
		}
		
		_leafsize(root->_left);
		_leafsize(root->_right);

		return size;
	}

	size_t _GetKLevel(int k)
	{
		if (_root == NULL)
		{
			return 0;
		}

		if (k == 1)
		{
			return 1;
		}


		Node* cur = _root;
		static size_t LeafKSize = 0;
		static size_t Level = 1;

		if (Level == k - 1)
		{
			
			if (_root->_left != NULL)
			{
				leafsize++;
			}

			if (_root->_right != NULL)
			{
				leafsize++;
			}

		}

		Level++;
		_GetKLevel(_root->_left);
		_GetKLevel(_root->_right);
	}

	void _levelOrder(Node* root)
	{
		if (root == NULL)
		{
			return;
		}
		queue<Node*> qTree;
		qTree.push(root);
		while (!qTree.empty())
		{
			Node* cur = qTree.front();
			qTree.pop();
			cout << cur->_data << " ";
			if (cur->_left)
			{
				qTree.push(cur->_left);
			}

			if (cur->_right)
			{
				qTree.push(cur->_right);
			}
		}
		cout << endl;
	}
	

protected:
	Node* _root;
};

 以上就是本人在學習過程中的一些經驗總結。當然,本人能力有限,難免會有紕漏,希望大家可以指正。

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