二叉树

一、二叉树

是结点的一个有限集合,每个根结点最多只有两颗子树,二叉树有左右之分,子树的次序不能颠倒。

二、二叉树的种类

1.满二叉树:每个结点都有左右子树,且叶结点都在同一层。

2.完全二叉树:一颗有N个结点的树,与满二叉树的前N个结点结构相同。

三、性质

1.度为0的结点的个数=度为2的结点的个数+1

2.以层序的方式对结点进行编号,规定第一个结点(根结点)为0。

1)i大于0时,其父母结点为(i-1)/2

2)序号为i的结点的左孩子为2i+1,右孩子为2i+2

四、二叉树的基本操作

1.二叉树的遍历

有前序(根左右),中序(左根右),后续(左右根),层序四种遍历方式

2.访问指对结点进行一些操作

五、操作代码

#define _CRT_SECURE_NO_WARNINGS	
#include <iostream>
#include <queue>
using namespace std;

template<class T>
struct BinTreeNode
{
	BinTreeNode(const T& data)  //结构体构造函数
	:_left(NULL)
	, _right(NULL)
	, _data(data)
	{}
	BinTreeNode<T>* _left;
	BinTreeNode<T>* _right;
	T _data;
};

template<class T>
class BinTree
{
	typedef BinTreeNode<T>* pNode;
	typedef BinTreeNode<T> Node;
public:
	BinTree()
		: _pRoot(NULL)
	{}
	BinTree(const T* array, size_t size, const T& invalid)
	{
		size_t index = 0;//常数0不能引用
		_CreateBinTree(_pRoot, array, size, index, invalid);
	}
	//拷贝构造函数,一个一个初始化
	BinTree(const BinTree& bt)
	{
		_pRoot=_CopyBinTree(bt._pRoot);
	}
	//赋值运算符的重载,赋地址
	BinTree& operator=(const BinTree& bt)
	{
		//删除旧空间
		_DestroyBinTree(_pRoot);
		_pRoot = _CopyBinTree(bt._pRoot);
		return *this;
	}
	~BinTree()
	{
		_DestroyBinTree(_pRoot);
	}
	void PreOrder()
	{
		cout << "前序打印->";
		_PreOrder(_pRoot);
	}
	void InOrder()
	{
		cout << "中序打印->";
		_InOrder(_pRoot);
	}
	void PostOrder()
	{
		cout << "后序打印->";
		_PostOrder(_pRoot);
	}
	//层序遍历
	void LevelOrder()
	{
		cout << "层序打印->";
		_LevelOrder(_pRoot);
	}
	size_t Size()
	{
		return _Size(_pRoot); 
	}
	size_t GetLeefCount()
	{
		return _GetLeefCount(_pRoot);
	}
	// 获取第K层结点的个数 
	size_t GetKLevelCount(size_t K)
	{
		return _GetKLevelCount(_pRoot, K);
	}
	size_t Height()
	{
		return _Height(_pRoot);
	}
	pNode Find(const T& data)
	{
		return _Find(_pRoot, data);
	}
	pNode Parent(pNode pnode)
	{
		return _Parent(_pRoot,pnode);
	}
	pNode LeftChild(pNode pnode)
	{
		return _LeftChild(_pRoot, pnode);
	}
	pNode RightChild(pNode pnode)
	{
		return _RightChild(_pRoot, pnode);
	}

private:
	// 根+左子树+右子树,前序创建 
	void _CreateBinTree(pNode& pRoot, const T* array, size_t size, size_t& index, const T& invalid)
	{
		if (array == NULL)
		{
			return;
		}
		pNode proot = NULL;
		while (index < size&&array[index] != invalid)//有效元素创建结点
		{
			proot = new Node(array[index]);  //创建一个结点
			_CreateBinTree(proot->_left, array, size, ++index,invalid);
			_CreateBinTree(proot->_right, array, size, ++index, invalid);
		}
		pRoot = proot;
	}
	//前序递归构造
	pNode _CopyBinTree(pNode pRoot)
	{
		if (_pRoot == pRoot)
		{
			return NULL;
		}
		pNode tmp = NULL;
		if (pRoot)
		{
			tmp = new Node(pRoot->_data);
			tmp->_left = _CopyBinTree(pRoot->_left);
			tmp->_right = _CopyBinTree(pRoot->_right);
		}
		_pRoot = tmp;
		return _pRoot;
	}
	//按照后序销毁,左-右-根
	void _DestroyBinTree(pNode pRoot)
	{
		if (pRoot == NULL)
		{
			return;
		}
		if (pRoot)
		{
			_DestroyBinTree(pRoot->_left);
			_DestroyBinTree(pRoot->_right);
			delete pRoot;
			pRoot = NULL;
		}
	}
	// 根--->左子树--->右子树 
	void _PreOrder(pNode pRoot)
	{
		if (pRoot == NULL)
		{
			return;
		}
		cout << pRoot->_data;
		_PreOrder(pRoot->_left);
		_PreOrder(pRoot->_right);
	}
	// 左子树--->根节点--->右子树 
	void _InOrder(pNode pRoot)
	{
		if (pRoot == NULL)
		{
			return;
		}
		_InOrder(pRoot->_left);
		cout << pRoot->_data;
		_InOrder(pRoot->_right);
	
	}
	// 左子树--->右子树--->根节点 
	void _PostOrder(pNode pRoot)
	{
		if (pRoot == NULL)
		{
			return;
		}
		_PostOrder(pRoot->_left);
		_PostOrder(pRoot->_right);
		cout << pRoot->_data;
	}
	//层序打印,保存左右结点
	void _LevelOrder(pNode pRoot)
	{
		if (_pRoot == NULL)
		{
			return;
		}
		queue<pNode> q;//队列中保存结点
		pNode root = _pRoot;
		q.push(root);
		while (!q.empty())
		{
			pNode head = q.front();
			cout << head->_data;
			q.pop();   //读取后弹出,先进先出
			if (head->_left)
			{
				q.push(head->_left);
			}
			if (head->_right)
			{
				q.push(head->_right);
			}
		}
	}
	size_t _Size(pNode pRoot)
	{
		if (pRoot == NULL)
		{
			return 0;
		}
		return _Size(pRoot->_left) + _Size(pRoot->_right) + 1;
	}
	size_t _GetLeefCount(pNode pRoot)
	{
		if (pRoot == NULL)
		{
			return 0;
		}
		if (pRoot->_left == NULL&&pRoot->_right == NULL)
		{
			return 1;
		}
		//左右子树都需要遍历
		return _GetLeefCount(pRoot->_left) + _GetLeefCount(pRoot->_right);
	}
	size_t _Height(pNode pRoot)
	{
		if (pRoot == NULL)
		{
			return 0;
		}
		if (pRoot->_left == NULL&&pRoot->_right == NULL)
		{
			return 1;
		}
		size_t lefth = _Height(pRoot->_left)+1;  //每遇到一层加一
		size_t righth = _Height(pRoot->_right)+1;
		return ((lefth > righth) ? lefth : righth);
	}
	pNode _Find(pNode pRoot, const T& data)
	{
		if (pRoot == NULL)
		{
			return NULL;
		}
		pNode root = pRoot;
		if (root->_data == data)
		{
			return root;
		}
		if (root->_left)
		{
			return _Find(pRoot->_left, data);
		}
		if (root->_right)
		{
			return _Find(pRoot->_right, data);
		}
	}
	size_t _GetKLevelCount(pNode pRoot, size_t K)
	{
		if (pRoot == NULL)
		{
			return 0;
		}
		if (K == 1)
		{
			return 1;  //第一层有一个结点
		}
		size_t leftcount = _GetKLevelCount(pRoot->_left, K - 1);//K为3,则调用两次
		size_t rightcount = _GetKLevelCount(pRoot->_right, K - 1);
		return leftcount + rightcount;
	}
	pNode _Parent(pNode pRoot, pNode pnode)
	{
		if (pnode == NULL || pRoot == NULL)
		{
			return NULL;
		}
		pNode proot = pRoot;
		if (proot->_left == pnode || proot->_right == pnode)
		{
			return proot;
		}
		if (proot->_left)
		{
			return _Parent(proot->_left,pnode);
		}
		if (proot->_right)
		{
			return _Parent(proot->_right,pnode);
		}
	}
	pNode _LeftChild(pNode pRoot,pNode pnode)
	{
		if (pRoot == NULL || pnode == NULL)
		{
			return NULL;
		}
		if (pRoot == pnode)
		{
			return pRoot->_left;
		}
		if (pRoot->_left)
		{
			return _LeftChild(pRoot->_left, pnode);
		}
		if (pRoot->_right)
		{
			return _LeftChild(pRoot->_right, pnode);
		}
	}
	pNode _RightChild(pNode pRoot, pNode pnode)
	{
		if (pRoot == NULL || pnode == NULL)
		{
			return NULL;
		}
		if (pRoot == pnode)
		{
			return pRoot->_right;
		}
		if (pRoot->_left)
		{
			return _RightChild(pRoot->_left, pnode);
		}
		if (pRoot->_right)
		{
			return _RightChild(pRoot->_right, pnode);
		}
	}
private:
	pNode _pRoot;
};
测试函数

#include "BinTree.h"

int main()
{
	char* arr = "ABD#G###CE##F##";
	BinTree<char> bt(arr,15,'#');
	BinTree<char> bt1;
	bt1 = bt;
	bt1.LevelOrder();
	cout<<bt1.RightChild(bt1.Find('D'));
	getchar();
	return 0;

}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值