二叉树的基本操作,以及相关面试题(C++实现)

【面试题】

1、创建二叉树

#include<iostream>
using namespace std;

template<class T>
struct BinTreeNode{
	BinTreeNode(const T& data)
	  : _pLeft(NULL)
	  , _pRight(NULL)
	  , _data(data)
	{}
    
	BinTreeNode<T>* _pLeft;
	BinTreeNode<T>* _pRight;
	T _data;
};

template<class T>
class BinTree{
	typedef BinTreeNode<T> Node;
	typedef Node* PNode;
public:
	BinTree()
		: _pRoot(NULL)
	{}

	BinTree(const T* array,size_t size,const T& invalid)
	{
		size_t index = 0;
		CreateBinTree(_pRoot, array, size,index,invalid);
	}


	~BinTree()
	{
		DestoryBinTree(_pRoot);
	}
void CreateBinTree(PNode& pRoot, const T* array, size_t size,size_t& index,const T& invalid)
	{
		if (index<size&&invalid!=array[index]){
			pRoot = new Node(array[index]);
			CreateBinTree(pRoot->_pLeft, array, size, ++index,invalid);
			CreateBinTree(pRoot->_pRight, array, size, ++index,invalid);
		}
	}

	PNode CopyBinTree(PNode pRoot)
	{
		PNode pNewNode = NULL;
		if (pRoot){
			pNewNode = new Node(pRoot->_data);
			if (pRoot->_pLeft)
				pNewNode->_pLeft = CopyBinTree(pRoot->_pLeft);
			if (pRoot->_pRight)
                pNewNode->_pRight = CopyBinTree(pRoot->_pRight);
		}
		return pNewNode;
	}

	void DestoryBinTree(PNode& pRoot)
	{
		if (pRoot){
			DestoryBinTree(pRoot->_pLeft);
			DestoryBinTree(pRoot->_pRight);
			delete pRoot;
			pRoot = NULL;
		}
	}
};

2、前/中/后遍历二叉树(递归&非递归)

        //前序遍历
	void PreOrder(PNode pRoot)
	{
		if (pRoot){
			cout << pRoot->_data << " ";
			PreOrder(pRoot->_pLeft);
			PreOrder(pRoot->_pRight);
		}
	}
	//非递归前序遍历
	void _PreOrder_Nor()
	{
		cout << "_PreOrder_Nor:";
		if (_pRoot == NULL)
			return;
		stack<PNode> s;
		s.push(_pRoot);
		while (!s.empty()){
			PNode pCur = s.top();
			cout << pCur->_data << " ";
			s.pop();
			if (pCur->_pRight)
				s.push(pCur->_pRight);
			if (pCur->_pLeft)
				s.push(pCur->_pLeft);
		}
		cout << endl;
	}

	//中序遍历
	void InOrder(PNode pRoot)
	{
		if (pRoot){
			InOrder(pRoot->_pLeft);
			cout << pRoot->_data << " ";
			InOrder(pRoot->_pRight);
		}
	}

	//非递归中序遍历
	void _InOrder_Nor()
	{
		cout << "_InOrder_Nor";
		if (_pRoot == NULL)
			return;
			stack<PNode> s;
			PNode pCur = _pRoot;
			while (pCur || !s.empty()){
				while (pCur){
					s.push(pCur);
					pCur = pCur->_pLeft;
				}
				pCur = s.top();
				cout << pCur->_data << " ";
				s.pop();
				pCur = pCur->_pRight;
			}
			cout << endl;
	}

	//后序遍历
	void EndOrder(PNode pRoot)
	{
		if (pRoot){
			EndOrder(pRoot->_pLeft);
			EndOrder(pRoot->_pRight);
			cout << pRoot->_data << " ";
		}
	}
	//非递归后序遍历
	void _EndOrder_Nor()
	{
		cout << "_EndOrder_Nor:";
		if (_pRoot == NULL)
			return;

		stack<PNode> s;
		PNode pCur = _pRoot;
		PNode pTmp = NULL;
		while (pCur || !s.empty()){
			while (pCur){
				s.push(pCur);
				pCur = pCur->_pLeft;
			}
			_pRoot = s.top();
			if (NULL == _pRoot->_pRight || _pRoot->_pRight == pTmp){
				cout << _pRoot->_data << " ";
				s.pop();
				pTmp = _pRoot;
			}
			else{
				pCur = _pRoot->_pRight;
			}	
		}
		cout << endl;
	}

3、层序遍历二叉树

void LevelOrder(PNode pRoot)
	{
		if (NULL == pRoot)
			return;
		queue<PNode> q;
		q.push(pRoot);
		while (!q.empty()){
			PNode pCur = q.front();
			cout << pCur->_data <<" " ;
			if (pCur->_pLeft)
				q.push(pCur->_pLeft);
			if (pCur->_pRight)
				q.push(pCur->_pRight);
			q.pop();
		}
		cout << endl;
	}

4、求二叉树的高度

size_t Height(PNode pRoot)
	{
		if (NULL == pRoot)
			return 0;
		if (NULL == pRoot->_pLeft&&NULL == pRoot->_pRight)
			return 1;
		size_t LeftHeight = Height(pRoot->_pLeft);
		size_t RightHeight = Height(pRoot->_pRight);
		return LeftHeight > RightHeight ? (LeftHeight + 1) : (RightHeight + 1);
	}

5、求二叉树中结点的个数

size_t Size(PNode pRoot)
	{
		if (NULL == pRoot)
			return 0;
		return Size(pRoot->_pLeft) + Size(pRoot->_pRight) + 1;
	}

6、求叶子结点的个数

size_t GetLeaf(PNode pRoot)
	{
		if (NULL == pRoot)
			return 0;
		if (NULL == pRoot->_pLeft&&NULL == pRoot->_pRight)
			return 1;
		return GetLeaf(pRoot->_pLeft) + GetLeaf(pRoot->_pRight);
	}

7、求二叉树中第k层结点的个数

size_t GetKLevelNode(PNode pRoot,size_t K)
	{
		if (NULL == pRoot ||K == 0)
			return 0;
		if (K == 1)
			return 1;
		return GetKLevelNode(pRoot->_pLeft, K-1) + GetKLevelNode(pRoot->_pRight, K-1);
	}

8、判断一个节点是否在一棵二叉树中

bool IsNodeInBinTree(PNode pRoot, PNode pNode)
	{
		if (NULL == pRoot || NULL == pNode)
			return false;
		if (pRoot == pNode)
			return true;
		bool IsIn = false;
		if (IsIn = IsNodeInBinTree(pRoot->_pLeft, pNode))
			return true;
		return IsNodeInBinTree(pRoot->_pRight, pNode);
	}

 

9、判断一棵二叉树是否是完全二叉树

bool IsComporeBinTree()
	{
		if (_pRoot == NULL)
			return true;
		bool IsFlag = false;
		queue<PNode> q;
		q.push(_pRoot);
		while (!q.empty()){
			PNode pCur = q.front();
			if (IsFlag){
				if (pCur->_pLeft || pCur->_pRight)
					return true;
			}
			if (pCur->_pLeft&&pCur->_pRight){
				q.push(pCur->_pLeft);
				q.push(pCur->_pRight);
			}
			else if (pCur->_pLeft){
				q.push(pCur->_pLeft);
				IsFlag = true;
			}
			else if (pCur->_pRight)
				return false;
			else
				IsFlag = true;
			q.pop();
		}
		return true;
	}

10、求二叉树的镜像 

	void PreMarroy(PNode pRoot)
	{
		if (pRoot){
			swap(pRoot->_pLeft, pRoot->_pRight);
			cout << pRoot->_data << " ";
			PreMarroy(pRoot->_pLeft);
			PreMarroy(pRoot->_pRight);
		}
	}

	void InMarroy(PNode pRoot)
	{
		if (pRoot){
			swap(pRoot->_pLeft, pRoot->_pRight);
			InMarroy(pRoot->_pLeft);
			cout << pRoot->_data << " ";
			InMarroy(pRoot->_pRight);
		}
	}

	void EndMarroy(PNode pRoot)
	{
		if (pRoot){
			swap(pRoot->_pLeft, pRoot->_pRight);
			EndMarroy(pRoot->_pLeft);
			EndMarroy(pRoot->_pRight);
			cout << pRoot->_data << " ";
		}
	}

	void FeiMarroy(PNode pRoot)
	{
		if (pRoot == NULL)
			return;
		queue<PNode> q;
		q.push(pRoot);

		while (!q.empty()){
			PNode pCur = q.front();
			swap(pCur->_pLeft, pCur->_pRight);
			if (pCur->_pLeft)
				q.push(pCur->_pLeft);
			if (pCur->_pRight)
				q.push(pCur->_pRight);
			q.pop();
			cout << pCur->_data <<" ";
		}
	}


整体代码:

#include<iostream>
#include<string.h>
#include<queue>
#include<stack>
using namespace std;

template<class T>
struct BinTreeNode{
	BinTreeNode(const T& data)
	  : _pLeft(NULL)
	  , _pRight(NULL)
	  , _data(data)
	{}
    
	BinTreeNode<T>* _pLeft;
	BinTreeNode<T>* _pRight;
	T _data;
};

template<class T>
class BinTree{
	typedef BinTreeNode<T> Node;
	typedef Node* PNode;
public:
	BinTree()
		: _pRoot(NULL)
	{}

	BinTree(const T* array,size_t size,const T& invalid)
	{
		size_t index = 0;
		CreateBinTree(_pRoot, array, size,index,invalid);
	}

	//BinTree<T>& operator=(const BinTree<T>& bt)
	//{
	//	if (this != &bt){
	//		DestoryBinTree(_pRoot);
	//		_pRoot = CopyBinTree(bt->_pRoot);
	//	}
	//	return *this;
	//}

	~BinTree()
	{
		DestoryBinTree(_pRoot);
	}

	//前序遍历
	void _PreOrder()
	{
		cout << "_PreOrder:" ;
		PreOrder(_pRoot);
		cout << endl;
	}

	//非递归前序遍历
	void _PreOrder_Nor()
	{
		cout << "_PreOrder_Nor:";
		if (_pRoot == NULL)
			return;
		stack<PNode> s;
		s.push(_pRoot);
		while (!s.empty()){
			PNode pCur = s.top();
			cout << pCur->_data << " ";
			s.pop();
			if (pCur->_pRight)
				s.push(pCur->_pRight);
			if (pCur->_pLeft)
				s.push(pCur->_pLeft);
		}
		cout << endl;
	}

	//中序遍历
	void _InOrder()
	{
		cout << "_InOrder:";
		InOrder(_pRoot);
		cout << endl;
	}	

	//非递归中序遍历
	void _InOrder_Nor()
	{
		cout << "_InOrder_Nor";
		if (_pRoot == NULL)
			return;
			stack<PNode> s;
			PNode pCur = _pRoot;
			while (pCur || !s.empty()){
				while (pCur){
					s.push(pCur);
					pCur = pCur->_pLeft;
				}
				pCur = s.top();
				cout << pCur->_data << " ";
				s.pop();
				pCur = pCur->_pRight;
			}
			cout << endl;
	}

	//后序遍历
	void _EndOrder()
	{
		cout << "_EndOrder:";
		EndOrder(_pRoot);
		cout << endl;
	}

	//非递归后序遍历
	void _EndOrder_Nor()
	{
		cout << "_EndOrder_Nor:";
		if (_pRoot == NULL)
			return;

		stack<PNode> s;
		PNode pCur = _pRoot;
		PNode pTmp = NULL;
		while (pCur || !s.empty()){
			while (pCur){
				s.push(pCur);
				pCur = pCur->_pLeft;
			}
			_pRoot = s.top();
			if (NULL == _pRoot->_pRight || _pRoot->_pRight == pTmp){
				cout << _pRoot->_data << " ";
				s.pop();
				pTmp = _pRoot;
			}
			else{
				pCur = _pRoot->_pRight;
			}	
		}
		cout << endl;
	}

	//层序遍历
	void _LevelOrder()
	{
		cout << "_LevelOrder:";
		LevelOrder(_pRoot);
		cout << endl;
	}

	//求树的高度
	void _Height()
	{
		cout << "_Height:";
		size_t p;
		p=Height(_pRoot);
		cout << p << endl;
	}

	//树的节点个数
	void _Size()
	{
		cout << "_Size:";
		size_t p;
		p = Size(_pRoot);
		cout << p << endl;
	}

	//树的叶子节点个数
	void _GetLeaf()
	{
		cout << "_GetLeaf:";
		size_t p;
		p = GetLeaf(_pRoot);
		cout << p << endl;
	}

	//第K层节点个数
	void _GetKLevelNode(size_t K)
	{
		cout << "_GetKLevelNode:";
		size_t p;
		p = GetKLevelNode(_pRoot,K);
		cout << p << endl;
	}

	//查找结点是否存在
	void _IsNodeInBinTree(PNode pNode)
	{
		cout << "_IsNodeInBinTree:";
		bool p;
		p=IsNodeInBinTree(_pRoot,pNode);
		if (p == true)
			cout << "存在" << endl;
		if (p == false)
			cout << "不存在" << endl;
	}

	//查找结点
	PNode _Find(const T& data)
	{
		return Find(_pRoot, data);
	}

	//判断二叉树是否为完全二叉树
	void _IsComporeBinTree()
	{
		cout << "_IsComporeBinTree:";
		bool p;
		p = IsComporeBinTree();
		if (p == true)
			cout << "是完全二叉树" << endl;
		if (p == false)
			cout << "不是完全二叉树" << endl;
	}

    //求二叉树的镜像
	void _PreMarroy()
	{
		cout << "_PreMarroy:";
		PreMarroy(_pRoot);
		cout << endl;
	}	
	
	void _InMarroy()
	{
		cout << "_InMarroy:";
		InMarroy(_pRoot);
		cout << endl;
	}

	void _EndMarroy()
	{
		cout << "_EndMarroy:";
		EndMarroy(_pRoot);
		cout << endl;
	}

	//非递归的方法求二叉树的镜像
	void _FeiMarroy()
	{
		cout << "_FeiMarroy:";
		FeiMarroy(_pRoot);
		cout << endl;
	}

private:
	void CreateBinTree(PNode& pRoot, const T* array, size_t size,size_t& index,const T& invalid)
	{
		if (index<size&&invalid!=array[index]){
			pRoot = new Node(array[index]);
			CreateBinTree(pRoot->_pLeft, array, size, ++index,invalid);
			CreateBinTree(pRoot->_pRight, array, size, ++index,invalid);
		}
	}

	PNode CopyBinTree(PNode pRoot)
	{
		PNode pNewNode = NULL;
		if (pRoot){
			pNewNode = new Node(pRoot->_data);
			if (pRoot->_pLeft)
				pNewNode->_pLeft = CopyBinTree(pRoot->_pLeft);
			if (pRoot->_pRight)
                pNewNode->_pRight = CopyBinTree(pRoot->_pRight);
		}
		return pNewNode;
	}

	void DestoryBinTree(PNode& pRoot)
	{
		if (pRoot){
			DestoryBinTree(pRoot->_pLeft);
			DestoryBinTree(pRoot->_pRight);
			delete pRoot;
			pRoot = NULL;
		}
	}

	void PreOrder(PNode pRoot)
	{
		if (pRoot){
			cout << pRoot->_data << " ";
			PreOrder(pRoot->_pLeft);
			PreOrder(pRoot->_pRight);
		}
	}

	void InOrder(PNode pRoot)
	{
		if (pRoot){
			InOrder(pRoot->_pLeft);
			cout << pRoot->_data << " ";
			InOrder(pRoot->_pRight);
		}
	}

	void EndOrder(PNode pRoot)
	{
		if (pRoot){
			EndOrder(pRoot->_pLeft);
			EndOrder(pRoot->_pRight);
			cout << pRoot->_data << " ";
		}
	}

	void LevelOrder(PNode pRoot)
	{
		if (NULL == pRoot)
			return;
		queue<PNode> q;
		q.push(pRoot);
		while (!q.empty()){
			PNode pCur = q.front();
			cout << pCur->_data <<" " ;
			if (pCur->_pLeft)
				q.push(pCur->_pLeft);
			if (pCur->_pRight)
				q.push(pCur->_pRight);
			q.pop();
		}
		cout << endl;
	}

	size_t Height(PNode pRoot)
	{
		if (NULL == pRoot)
			return 0;
		if (NULL == pRoot->_pLeft&&NULL == pRoot->_pRight)
			return 1;
		size_t LeftHeight = Height(pRoot->_pLeft);
		size_t RightHeight = Height(pRoot->_pRight);
		return LeftHeight > RightHeight ? (LeftHeight + 1) : (RightHeight + 1);
	}

	size_t Size(PNode pRoot)
	{
		if (NULL == pRoot)
			return 0;
		return Size(pRoot->_pLeft) + Size(pRoot->_pRight) + 1;
	}

	size_t GetLeaf(PNode pRoot)
	{
		if (NULL == pRoot)
			return 0;
		if (NULL == pRoot->_pLeft&&NULL == pRoot->_pRight)
			return 1;
		return GetLeaf(pRoot->_pLeft) + GetLeaf(pRoot->_pRight);
	}

	size_t GetKLevelNode(PNode pRoot,size_t K)
	{
		if (NULL == pRoot ||K == 0)
			return 0;
		if (K == 1)
			return 1;
		return GetKLevelNode(pRoot->_pLeft, K-1) + GetKLevelNode(pRoot->_pRight, K-1);
	}

	bool IsNodeInBinTree(PNode pRoot, PNode pNode)
	{
		if (NULL == pRoot || NULL == pNode)
			return false;
		if (pRoot == pNode)
			return true;
		bool IsIn = false;
		if (IsIn = IsNodeInBinTree(pRoot->_pLeft, pNode))
			return true;
		return IsNodeInBinTree(pRoot->_pRight, pNode);
	}

	PNode Find(PNode pRoot, const T& data)
	{
		if (NULL == pRoot)
			return NULL;
		if (pRoot->_data == data)
			return pRoot;
		PNode _data = NULL;
		if (_data = Find(pRoot->_pLeft, data))
			return _data;
		return Find(pRoot->_pRight, data);
	}

	bool IsComporeBinTree()
	{
		if (_pRoot == NULL)
			return true;
		bool IsFlag = false;
		queue<PNode> q;
		q.push(_pRoot);
		while (!q.empty()){
			PNode pCur = q.front();
			if (IsFlag){
				if (pCur->_pLeft || pCur->_pRight)
					return true;
			}
			if (pCur->_pLeft&&pCur->_pRight){
				q.push(pCur->_pLeft);
				q.push(pCur->_pRight);
			}
			else if (pCur->_pLeft){
				q.push(pCur->_pLeft);
				IsFlag = true;
			}
			else if (pCur->_pRight)
				return false;
			else
				IsFlag = true;
			q.pop();
		}
		return true;
	}

	void PreMarroy(PNode pRoot)
	{
		if (pRoot){
			swap(pRoot->_pLeft, pRoot->_pRight);
			cout << pRoot->_data << " ";
			PreMarroy(pRoot->_pLeft);
			PreMarroy(pRoot->_pRight);
		}
	}

	void InMarroy(PNode pRoot)
	{
		if (pRoot){
			swap(pRoot->_pLeft, pRoot->_pRight);
			InMarroy(pRoot->_pLeft);
			cout << pRoot->_data << " ";
			InMarroy(pRoot->_pRight);
		}
	}

	void EndMarroy(PNode pRoot)
	{
		if (pRoot){
			swap(pRoot->_pLeft, pRoot->_pRight);
			EndMarroy(pRoot->_pLeft);
			EndMarroy(pRoot->_pRight);
			cout << pRoot->_data << " ";
		}
	}

	void FeiMarroy(PNode pRoot)
	{
		if (pRoot == NULL)
			return;
		queue<PNode> q;
		q.push(pRoot);

		while (!q.empty()){
			PNode pCur = q.front();
			swap(pCur->_pLeft, pCur->_pRight);
			if (pCur->_pLeft)
				q.push(pCur->_pLeft);
			if (pCur->_pRight)
				q.push(pCur->_pRight);
			q.pop();
			cout << pCur->_data <<" ";
		}
	}

private:
	PNode _pRoot;
};


void Test(){
	char* arr = "ABD###CE##F";
	BinTree<char> bt(arr, strlen(arr), '#');
	bt._PreOrder();
	bt._PreOrder_Nor();
	bt._InOrder();
	bt._InOrder_Nor();
	bt._EndOrder();
	bt._EndOrder_Nor();
	bt._LevelOrder();
	bt._Height();
	bt._Size();
	bt._GetLeaf();
	bt._GetKLevelNode(1);
	BinTreeNode<char>* pNode = bt._Find('b');
	BinTreeNode<char>* pNode1 = bt._Find('B');
	bt._IsNodeInBinTree(pNode);
	bt._IsNodeInBinTree(pNode1);
	BinTree<char> bt1(bt);
	bt._IsComporeBinTree();
	bt._PreMarroy();
	bt._InMarroy();
	bt._EndMarroy();
	bt._FeiMarroy();

	BinTree<char> bt2;
	bt2 = bt;
}

int main(){
	Test();
	return 0;
}

测试结果截图:

测试截图

 

  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值