二叉树的概念和基本操作

**二叉树概念**一棵二叉树是结点的一个有限集合,该集合可为空,或者是由一个根节点加上左子树和右子树的二叉树组成。

**二叉树的特点**

1.每个结点最多有两棵子树,即二叉树不存在度大于2的结点(分支数最大不超过2)

2.二叉树的子树有左右之分,其子树的次序不能颠倒

**满二叉树**:在一棵二叉树中,如果所有分支结点都存在左子树和右子树,并且所有叶子节点都在同一层上。

**完全二叉树**:如果一棵具有N个结点的二叉树的结构与满二叉树的前N个结点的结构相同,称为完全二叉树。

**二叉树的性质**

1、若规定根节点的层数为0,则一棵非空二叉树的第i层上最多有2^i(i>=0)个结点

2、若规定只有根节点的二叉树的深度为0,则深度为K的二叉树的最大结点数是2^(k+1) -1 (k>=-1)

3、对任何一棵二叉树, 如果其叶结点个数为 n0, 度为2的非叶结点个数为 n2,则有n0=n2+1

4、具有n个结点的完全二叉树的深度k为大于或等于(2为底)log2(n+1)-1的最小整数(向上取整)

5、对于具有n个结点的完全二叉树,如果按照从上至下从左至右的顺序对所有节点从0开始编号,则对于序号为i的结点有:a>:如果i>0,则序号为i结点的双亲结点的序号为(i-1)/2;如果i=0,则序号为i的结点为根节点,

b>:如果2i+1<n(在该树范围内),则序号为i的结点的左孩子结点的序号为2i+1

c>:如果2i+2<n,则序号为i结点的右孩子结点的序号为2i+2


Ex1:深度为6的 满二叉树有31个分支节点,有多少叶子节点?

  n0=n2+1; 2^6-1=63(总节点个数) --->2n2+1=63--->n2=31--->63-31=32(叶子节点)--->性质3

Ex2:一棵有257个节点的完全二叉树,深度?

  log2(257)  向上取整  =9  --->性质4

Ex3:一棵完全二叉树有71个节点,有多少叶子节点?

不难看出节点个数为奇数时,没有度为1的节点,故n0+n1+n2=71--->2n2+1=71--->n2=35--->n0=36;

--------------------------------------------------------

二叉树的创建:

//孩子表示法
template <class T>
struct BinaryTreeNode
{
	BinaryTreeNode(const T& value)
	:_value(value)
	, _pLeft(NULL)
	, _pRight(NULL)
	{}

	T _value;
	BinaryTreeNode<T>* _pLeft;
	BinaryTreeNode<T>* _pRight;
};

//二叉树的构建
template <class T>
struct BinaryTree
{
	typedef BinaryTreeNode<T> Node;
	BinaryTree()
		:_pRoot(NULL)
	{}

	BinaryTree(const T array[], size_t size, const T& invalid)
	{
		size_t index = 0;
		_CreateBinaryTree(_pRoot, array, size, index, invalid);
	}

	BinaryTree(const BinaryTree<T>& bt)
	{
		_pRoot = _CopyBinaryTree(bt._pRoot);
	}

	BinaryTree<T>& operator=(const BinaryTree<T>& bt)
	{
		if (this != &bt)
		{
			_DestoryBinaryTree(_pRoot);
			_pRoot = _CopBinaryTree(bt._pRoot);
		}
		return *this;
	}

	~BinaryTree()
	{
		_DestoryBinaryTree(_pRoot);
	}

	void _CreateBinaryTree(Node* &pRoot, const T array[], size_t size, size_t & index, const T& invalid)
	{
		if (index < size && invalid != array[index])
		{
			pRoot = new Node(array[index]);//创建根节点
			_CreateBinaryTree(pRoot->_pLeft, array, size, ++index, invalid);
			_CreateBinaryTree(pRoot->_pRight, array, size, ++index, invalid);
		}
	}

	Node* _CopyBinTree(Node* pRoot)
	{
		Node* pNewRoot = NULL;
		if (pRoot)
		{
			pNewRoot = new Node(pRoot->_value);	//拷贝根节点
			pNewRoot->_pLeft = _CopyBinTree(pRoot->_pLeft);//拷贝左子树
			pNewRoot->_pRight = _CopyBinTree(pRoot->_pRight);//拷贝右子树
		}
		return pNewRoot;
	}

	void _DestoryBinaryTree(Node*& pRoot)
	{
		if (pRoot)
		{
			_DestoryBinaryTree(pRoot->_pLeft);
			_DestoryBinaryTree(pRoot->_pRight);
			delete pRoot;
			pRoot = NULL;
		}
	}



二叉树的基本操作:

//递归

//求二叉树结点个数
//1.如果root为空,返回0
//2.返回左子树节点个数+右子树节点个数+1
size_t _Size(Node* root)
{
	if (NULL == root)
		return 0;
	return size_t Size(root->left) + size_t Size(root->right)+1;
	
}

//求叶子节点的个数
//1.root为空,返回0
//2.只有root 一个节点,返回1
//3.返回左子树叶子个数+右子树节点个数
size_t _LeafSize(Node* root)
{
	if (NULL == root)
		return 0;
	else (NULL == root->left && NULL == root->right)
		return 1;
	
	return  _LeafSize(root->left) + size_t _LeafSize(root->rihgt);

}

//求第K 层节点的个数
//1.root 为空,返回0
//2.k = 1,返回1
//3.返回左右子树的K-1 层节点个数和
size_t GetKSize(Node* root, size_t k)
{
	if (NULL == root)
		return 0;
	if (k == 1)
		return 1;
	return  GetKSize(root->left, k - 1) + size_t GetKSize(root->right, k - 1);
}

//求二叉树的深度
//1.root 为空,返回0
//2.只有根节点,返回1
//3.返回左右子树深度较大值+1
size_t _Depth(Node* root)
{
	if (NULL == root)
		return 0;
	if (NULL == root->left && NULL == root->right)//只有根节点
		return 1;
	
	return _Depth(root->left) > _Depth(root->right) ? _Depth(root->left) + 1 : _Depth(root->right)+1

}

//查找值为 x 的节点
//1.root为空,返回NULL
//2.root->data = x ,返回root
//3.左右子树查找,找到则返回,否则返回NULL

Node* _FindX(Node* root, const T& x)
{
	if (NULL == root)
		return NULL;
	if (root->data == x)
		return root;
	Node* ret = _FindX(root->left ,x);
	if (ret)
		return ret;
	return _FindX(root->right, x);
}


--------------------------------------------------------------


//求其父亲节点
	//(Node->left = pCur || Node->right = pCur ) 则Node 为pCur的父亲节点
	Node* _Parent(Node* pRoot, Node* pCur)
	{
		assert(NULL != pCur)
		if (NULL == pRoot || NULL == pCur)
			return NULL;
		if (pRoot->_pLeft == pCur || pRoot->_pRight == pCur)
			return pRoot;
		Node* parent = NULL;
		if (parent = _Parent(pRoot->_pLeft, pCur))
			return parent;
		return _Parent(pRoot->_pRight, pCur);
	}

	//求叶子节点的个数
	//左子树叶子节点数 + 右子树节点数 
	size_t _GetLeeNum(Node* pRoot)
	{
		if (NULL == pRoot)
			return 0;
		if (NULL == pRoot->_pLeft && NULL == pRoot->_pRight)
			return 1;
		return _GetLeeNum(pRoot->_pLeft) + _GetLeeNum(pRoot->_pRight);

	}

	// 镜像
	void _BinarryMirror(Node* pRoot)
	{
		if (pRoot)
		{
			std::swap(pRoot->_pLeft, pRoot->_pRight);
			_BinarryMirror(pRoot->_pLeft);
			_BinarryMirror(pRoot->_pRight);
		}
	}

	// 判断是否为完全二叉树
	bool _IsCompeleteBinarryTree()
	{
		if (NULL == _pRoot)
			return true;
		bool flag = false;
		queue<Node*> q;
		q.push(pRoot);
		while (!q.empty())
		{
			Node* pCur = q.front();
			if (flag)
			{
				if (pCur->_pLeft || pCur->_pRight)
					return false;
			}
			else
			{
				if (pCur->_pLeft && pCur->_pRight)
				{
					q.push(pCur->_pLeft);
					q.push(pCur->_pRight);
				}
				else if (pCur->_pLeft)
				{
					q.push(pCur->_pLeft);
					flag = true;
				}
				else if (pCur->_pRight)
				{
					q.push(pCur->_pRight);
					flag = true;
				}
				else
					return false;
			}
			q.pop();
		}
	}








评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值