二叉树面试题(一)
来源:互联网 发布:mac apache 默认目录 编辑:程序博客网 时间:2024/06/18 09:48
一、基本概念
1、二叉树的概念
一棵二叉树是结点的一个有限集合,该集合或者为空,或者是由一个根节点加上两棵分别称为左子树和右子树的二叉树组成(即一个根节点最多只有两个孩子结点)。
2、二叉树的特点
(1)每个结点最多有两棵子树,即二叉树不存在度大于2的结点(分支数最大不超过2)
(2)二叉树的子树有左右之分,其子树的次序不能颠倒
3、完全二叉树与满二叉树
(1)满二叉树:在一棵二叉树中,如果所有分支结点都存在左子树和右子树,并且所有叶子节点都在同一层上。
(2)完全二叉树:如果一棵具有N个结点的二叉树的结构与满二叉树的前N个结点的结构相同,称为完全二叉树。
4、二叉树的性质
(1)若规定根节点的层数为1,则一棵非空二叉树的第i层上最多有 2 i-1 (i>=1)个结点
(2)若规定只有根节点的二叉树的深度为1,则深度为K的二叉树的最大结点数是2 k -1(k>=0)
(3)对任何一棵二叉树, 如果其叶结点个数为 n0 , 度为2的非叶结点个数为 n2 ,则有n0 =n 2 +1
(4)具有n个结点的完全二叉树的深度k为log2(n+1)上取整。
(5)对于具有n个结点的完全二叉树,如果按照从上至下从左至右的顺序对所有节点从0开始编号,则对于序号为i的结点有:
二、二叉树的基本操作
1、二叉树的创建
利用前序的规则,即先创建根节点,然后在创建右节点,最后创建左结点
2、二叉树的四种遍历方式(均为递归+非递归)
(1)前序遍历:根节点—–>左孩子—–>右孩子
(2)中序遍历:左孩子—–>根节点—–>右孩子
(3)后序遍历:左孩子—–>右孩子—–>根节点
(4)层序遍历:即一层访问完成之后,才去进行下一层,在遍历当前层的时候,需要将当前层的当前结点的左右孩子保存在队列中,再将其当前结点弹出,直至队列中为空,利用队列+循环
3、二叉树的销毁
利用后序的规则,防止将根节点销毁之后,其的左孩子或者右孩子找不到
上面几个基本操作的代码如下所示:
//二叉树结点的定义 template<class T> struct BinTreeNode { //构造函数 BinTreeNode(const T&data) :_data(data) , _pLeft(NULL) , _pRight(NULL) {} BinTreeNode *_pLeft; BinTreeNode *_pRight; T _data; };
//二叉树的定义template<class T>class BinTree{ typedef BinTreeNode<T> Node; typedef BinTreeNode<T>* 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(const BinTree& bt) { _pRoot = _CopyBinTree(bt._pRoot); } //赋值运算符重载 BinTree& operator=(const BinTree& bt) { if (this != &bt) { //先销毁原来的树 _DestroyBinTree(_pRoot); //拷贝现在的树 _pRoot = _CopyBinTree(bt._pRoot); } return *this; } //四种遍历方式 //前序遍历(根节点---左子树---右子树) void PreOrder() { _PreOrder(_pRoot); cout << endl; } //非递归(循环+栈) void Preorder_No1() { _Preorder_No1(_pRoot); cout << endl; } void Preorder_No2() { _Preorder_No2(_pRoot); cout << endl; } //中序遍历(左子树----根节点---右子树) void InOrder() { _InOrder(_pRoot); cout << endl; } //非递归 void InOrder_No() { _InOrder_No(_pRoot); cout << endl; } //后序遍历(左子树--->右子树--->根节点) void PostOrder() { _PostOrder(_pRoot); cout << endl; } void PostOrder_No1() { _PostOrder_No1(_pRoot); cout << endl; } void PostOrder_No2() { _PostOrder_No2(_pRoot); cout << endl; } //层序遍历(利用容器,队列) void LevelOrder() { //空树 if (_pRoot == NULL) 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(); } }private://前序遍历 void _PreOrder(PNode& pRoot) { if (NULL == pRoot) return; if (pRoot) { cout << pRoot->_data << " "; _PreOrder(pRoot->_pLeft); _PreOrder(pRoot->_pRight); } } void _Preorder_No1(PNode &pRoot) { if (NULL == pRoot) return; PNode pCur; stack<PNode> s; s.push(_pRoot); while (!s.empty()) { pCur = s.top(); cout << pCur->_data << " "; s.pop(); //右子树入栈 if (pCur->_pRight) s.push(pCur->_pRight); //左子树入栈 if (pCur->_pLeft) s.push(pCur->_pLeft); } } void _Preorder_No2(PNode &pRoot) { if (NULL == pRoot) return; stack<PNode> s; s.push(pRoot); PNode pCur; while (!s.empty()) { pCur = s.top(); s.pop(); while (pCur) { cout << pCur->_data << " "; if (pCur->_pRight) s.push(pCur->_pRight); pCur = pCur->_pLeft; } } } //中序遍历 void _InOrder(PNode pRoot) { if (NULL == pRoot) return; if (pRoot) { _InOrder(pRoot->_pLeft); cout << pRoot->_data << " "; _InOrder(pRoot->_pRight); } } void _InOrder_No(PNode pRoot) { if (NULL == pRoot) return; PNode pCur = pRoot; stack<PNode> s; while (pCur || !s.empty()) { while (pCur) { s.push(pCur); pCur = pCur->_pLeft; } pCur = s.top(); cout << pCur->_data << " "; s.pop(); pCur = pCur->_pRight; } } //后序遍历 void _PostOrder(PNode pRoot) { if (NULL == pRoot) return; if (pRoot) { _PostOrder(pRoot->_pLeft); _PostOrder(pRoot->_pRight); cout << pRoot->_data << " "; } } void _PostOrder_No1(PNode pRoot) { if (NULL == pRoot) return; PNode pCur = pRoot; PNode pTop = NULL; PNode Prev = NULL; stack<PNode> s; while (pCur||!s.empty()) { //左子树入栈 while (pCur) { s.push(pCur); pCur = pCur->_pLeft; } //左子树入栈之后,取栈顶元素 pTop = s.top(); //判断栈顶元素是否有右子树 //右子树不存在,且右子树没有被访问 if (NULL == pTop->_pRight || Prev == pTop->_pRight) { //访问并弹出 cout << pTop->_data << " "; Prev = pTop; s.pop(); } else pCur = pTop->_pRight; } } void _PostOrder_No2(PNode pRoot) { if (NULL == pRoot) return; PNode pCur = pRoot; PNode Prev = NULL; stack<PNode> s; while (pCur || !s.empty()) { //左子树入栈 //这块pCur != Prev改变了pCur的指向,因此是为了防止循环入栈 while (pCur&&pCur != Prev) { s.push(pCur); pCur = pCur->_pLeft; } //这样防止形成死循环 if (s.empty()) return; //左子树入栈之后,取栈顶元素 pCur = s.top(); //判断栈顶元素是否有右子树 //右子树不存在,且右子树没有被访问 if (NULL == pCur->_pRight || Prev == pCur->_pRight) { //访问并弹出 cout << pCur->_data << " "; Prev = pCur; s.pop(); } else pCur = pCur->_pRight; } } //利用后序遍历 void _DestroyBinTree(PNode pRoot) { if (pRoot) { //销毁左子树 _DestroyBinTree(pRoot->_pLeft); //销毁右子树 _DestroyBinTree(pRoot->_pRight); //销毁根节点 delete pRoot; pRoot = NULL; } } 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 _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); } }private: PNode _pRoot;};
三、二叉树的面试题(此处均采用将函数封装起来,为了传参的方便,并且均为类中的函数)
1、求二叉树的高度
思路
空树—–>直接返回0
此树只有一个节点—->返回1(此处根节点所处的高度为1)
多个节点—->左右子树中,最大的高度在加一即可
//二叉树的深度(高度) size_t Height() { size_t count=_Height(_pRoot); return count; } //二叉树的深度(高度) size_t _Height(PNode pRoot) { if (NULL == pRoot) return 0; if (NULL == pRoot->_pLeft&&NULL == pRoot->_pRight) return 1; size_t left = _Height(pRoot->_pLeft); size_t right = _Height(pRoot->_pRight); return left >= right ? left + 1 : right + 1; }
2、求二叉树中结点的个数
思路:
空树—–>直接返回0
多个节点—->左+右+1
//返回二叉树中结点的个数 size_t Size() { size_t count = _Size(_pRoot); return count; } //返回二叉树中结点的个数 size_t _Size(PNode pRoot) { if (pRoot == NULL) return 0; return _Size(pRoot->_pLeft) + _Size(pRoot->_pRight) + 1; }
3、求叶子结点的个数
思路:
空树—–>直接返回0
此树只有一个节点—->返回1
多个节点—->左边的叶子的结点+右边的叶子结点
//返回叶子结点的个数 size_t GetLeefCount() { size_t count= _GetLeefCount(_pRoot); return count; } //返回叶子结点的个数 size_t _GetLeefCount(PNode pRoot) { if (NULL == pRoot) return 0; //只有一个根节点 if (NULL == pRoot->_pLeft&&NULL == pRoot->_pRight) return 1; //多个结点 return _GetLeefCount(pRoot->_pLeft) + _GetLeefCount(pRoot->_pRight); }
4、找某个结点的双亲结点
//找某个结点的双亲结点 PNode Parent(PNode node) { PNode pCur = _Parent(_pRoot, node); return pCur; } //找某个结点的双亲结点 PNode _Parent(PNode pRoot, PNode pNode) { //空树或者只有一个根节点的树 if (NULL == pRoot || (NULL == pRoot->_pLeft) && (NULL == pRoot->_pRight)) return NULL; if (pNode == pRoot->_pLeft || pNode == pRoot->_pRight) return pRoot; PNode parent; if(parent = _Parent(pRoot->_pLeft, pNode)) return parent; return _Parent(pRoot->_pRight, pNode); }
5、找某个结点的左孩子结点
//找某个结点的左孩子结点 PNode LeftChild(PNode pNode) { return (NULL == pNode) ? NULL : (pNode->_pLeft); }
6、找某个结点的右孩子结点
//找某个结点的右孩子结点 PNode RightChild(PNode pNode) { return (NULL == pNode) ? NULL : (pNode->_pRight); }
7、返回值为data的结点
思路:
为空树—->返回NULL
不是空树,判断data是否为根节点—->
是—–>返回根节点
不是—–>
与左子树比较—->是—->返回这个结点
与右子树比较—->是—->返回这个结点
//返回值为data的结点 PNode Find(const T& data) { PNode pCur = _Find(_pRoot, data); return pCur; } //返回值为data的结点 PNode _Find(PNode pRoot, const T& data) { if (NULL == pRoot) return NULL; if (data == pRoot->_data) return pRoot; //data不是根节点 PNode Ret; if (Ret = _Find(pRoot->_pLeft, data)) return Ret; return _Find(pRoot->_pRight,data); }
8、获取第K层结点的个数
思路:
判断K为有效值,判断是否为空树
走到第K层,让其左子树的结点个数+右子树的结点个数
// 获取第K层结点的个数 size_t GetKLevelCount(size_t K) { size_t count = _GetKLevelCount(_pRoot, K); return count; } // 获取第K层结点的个数 size_t _GetKLevelCount(PNode pRoot, size_t K) { if (1 > K > Height() || NULL == pRoot) return 0; if (K == 1) return 1; size_t left = _GetKLevelCount(pRoot->_pLeft, K-1); size_t right = _GetKLevelCount(pRoot->_pRight, K-1); return left + right; }
9、二叉树的镜像(反转)递归
思路:根节点不需要反转
先反转左子树,在反转右子树
//二叉树的镜像(反转)递归 void Mirror() { _Mirror(_pRoot); } void _Mirror(PNode pRoot) { if (NULL == pRoot) return; if (pRoot) { swap(pRoot->_pLeft, pRoot->_pRight); _Mirror(pRoot->_pLeft); _Mirror(pRoot->_pRight); } }
//非递归 void Mirror_No() { _Mirror_No(_pRoot); } void _Mirror_No(PNode pRoot) { if (NULL == pRoot) return; queue<PNode> q; q.push(pRoot); PNode pCur = NULL; while (!q.empty()) { pCur = q.front(); swap(pCur->_pLeft, pCur->_pRight); q.pop(); if (pCur->_pLeft) q.push(pCur->_pLeft); if (pCur->_pRight) q.push(pCur->_pRight); } }
完整代码如下所示:
#define _CRT_SECURE_NO_WARNINGS 1#include<iostream>using namespace std;#include<queue>#include<stack>//二叉树结点的定义template<class T>struct BinTreeNode{ //构造函数 BinTreeNode(const T&data) :_data(data) , _pLeft(NULL) , _pRight(NULL) {} BinTreeNode *_pLeft; BinTreeNode *_pRight; T _data;};//二叉树的定义template<class T>class BinTree{ typedef BinTreeNode<T> Node; typedef BinTreeNode<T>* 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(const BinTree& bt) { _pRoot = _CopyBinTree(bt._pRoot); } //赋值运算符重载 BinTree& operator=(const BinTree& bt) { if (this != &bt) { //先销毁原来的树 _DestroyBinTree(_pRoot); //拷贝现在的树 _pRoot = _CopyBinTree(bt._pRoot); } return *this; } //四种遍历方式 //前序遍历(根节点---左子树---右子树) void PreOrder() { _PreOrder(_pRoot); cout << endl; } //非递归(循环+栈) void Preorder_No1() { _Preorder_No1(_pRoot); cout << endl; } void Preorder_No2() { _Preorder_No2(_pRoot); cout << endl; } //中序遍历(左子树----根节点---右子树) void InOrder() { _InOrder(_pRoot); cout << endl; } //非递归 void InOrder_No() { _InOrder_No(_pRoot); cout << endl; } //后序遍历(左子树--->右子树--->根节点) void PostOrder() { _PostOrder(_pRoot); cout << endl; } void PostOrder_No1() { _PostOrder_No1(_pRoot); cout << endl; } void PostOrder_No2() { _PostOrder_No2(_pRoot); cout << endl; } //判断一棵树是否是完全二叉树 bool IsCompleteTree() { if (NULL == _pRoot) return true; queue<PNode> q; q.push(_pRoot); bool flag = false; while (!q.empty()) { PNode pCur = q.front(); //左子树不存在,右子树存在(不是) if (NULL == pCur->_pLeft&&pCur->_pRight) { return false; } //相当于已经取到下一次的队头 if (flag && (pCur->_pLeft != NULL || pCur->_pRight != NULL)) return false; //左子树或者右子树不存在 if (pCur->_pLeft == NULL || pCur->_pRight == NULL) flag = true; if (pCur->_pLeft) q.push(pCur->_pLeft); if (pCur->_pRight) q.push(pCur->_pRight); q.pop(); } return true; } bool IsCompleteTree1() { if (NULL == _pRoot) return true; queue<PNode> q; q.push(_pRoot); bool flag = false; PNode pCur = NULL; while (!q.empty()) { pCur = q.front(); q.pop(); if (pCur->_pLeft) { if (flag) return false; q.push(pCur->_pLeft); } else { flag = true; } if (pCur->_pRight) { if (flag) return false; q.push(pCur->_pRight); } else { flag = true; } } return true; } //层序遍历(利用容器,队列) void LevelOrder() { //空树 if (_pRoot == NULL) 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(); } } //返回二叉树中结点的个数 size_t Size() { size_t count = _Size(_pRoot); return count; } //返回叶子结点的个数 size_t GetLeefCount() { size_t count= _GetLeefCount(_pRoot); return count; } //二叉树的深度(高度) size_t Height() { size_t count=_Height(_pRoot); return count; } //返回值为data的结点 PNode Find(const T& data) { PNode pCur = _Find(_pRoot, data); return pCur; } //找某个结点的双亲结点 PNode Parent(PNode node) { PNode pCur = _Parent(_pRoot, node); return pCur; } //找某个结点的左孩子结点 PNode LeftChild(PNode pNode) { return (NULL == pNode) ? NULL : (pNode->_pLeft); } //找某个结点的右孩子结点 PNode RightChild(PNode pNode) { return (NULL == pNode) ? NULL : (pNode->_pRight); } // 获取第K层结点的个数 size_t GetKLevelCount(size_t K) { size_t count = _GetKLevelCount(_pRoot, K); return count; } //析构函数 ~BinTree() { _DestroyBinTree(_pRoot); } //二叉树的镜像(反转)递归 void Mirror() { _Mirror(_pRoot); } //非递归 void Mirror_No() { _Mirror_No(_pRoot); }private: //返回二叉树中结点的个数 size_t _Size(PNode pRoot) { if (pRoot == NULL) return 0; return _Size(pRoot->_pLeft) + _Size(pRoot->_pRight) + 1; } //返回叶子结点的个数 size_t _GetLeefCount(PNode pRoot) { if (NULL == pRoot) return 0; //只有一个根节点 if (NULL == pRoot->_pLeft&&NULL == pRoot->_pRight) return 1; //多个结点 return _GetLeefCount(pRoot->_pLeft) + _GetLeefCount(pRoot->_pRight); } //二叉树的深度(高度) size_t _Height(PNode pRoot) { if (NULL == pRoot) return 0; if (NULL == pRoot->_pLeft&&NULL == pRoot->_pRight) return 1; size_t left = _Height(pRoot->_pLeft); size_t right = _Height(pRoot->_pRight); return left >= right ? left + 1 : right + 1; } //返回值为data的结点 PNode _Find(PNode pRoot, const T& data) { if (NULL == pRoot) return NULL; if (data == pRoot->_data) return pRoot; //data不是根节点 PNode Ret; if (Ret = _Find(pRoot->_pLeft, data)) return Ret; return _Find(pRoot->_pRight,data); } //找某个结点的双亲结点 PNode _Parent(PNode pRoot, PNode pNode) { //空树或者只有一个根节点的树 if (NULL == pRoot || (NULL == pRoot->_pLeft) && (NULL == pRoot->_pRight)) return NULL; if (pNode == pRoot->_pLeft || pNode == pRoot->_pRight) return pRoot; PNode parent; if(parent = _Parent(pRoot->_pLeft, pNode)) return parent; return _Parent(pRoot->_pRight, pNode); } // 获取第K层结点的个数 size_t _GetKLevelCount(PNode pRoot, size_t K) { if (1 > K > Height() || NULL == pRoot) return 0; if (K == 1) return 1; size_t left = _GetKLevelCount(pRoot->_pLeft, K-1); size_t right = _GetKLevelCount(pRoot->_pRight, K-1); return left + right; } void _Mirror(PNode pRoot) { if (NULL == pRoot) return; if (pRoot) { swap(pRoot->_pLeft, pRoot->_pRight); _Mirror(pRoot->_pLeft); _Mirror(pRoot->_pRight); } } void _Mirror_No(PNode pRoot) { if (NULL == pRoot) return; queue<PNode> q; q.push(pRoot); PNode pCur = NULL; while (!q.empty()) { pCur = q.front(); swap(pCur->_pLeft, pCur->_pRight); q.pop(); if (pCur->_pLeft) q.push(pCur->_pLeft); if (pCur->_pRight) q.push(pCur->_pRight); } } //前序遍历 void _PreOrder(PNode& pRoot) { if (NULL == pRoot) return; if (pRoot) { cout << pRoot->_data << " "; _PreOrder(pRoot->_pLeft); _PreOrder(pRoot->_pRight); } } void _Preorder_No1(PNode &pRoot) { if (NULL == pRoot) return; PNode pCur; stack<PNode> s; s.push(_pRoot); while (!s.empty()) { pCur = s.top(); cout << pCur->_data << " "; s.pop(); //右子树入栈 if (pCur->_pRight) s.push(pCur->_pRight); //左子树入栈 if (pCur->_pLeft) s.push(pCur->_pLeft); } } void _Preorder_No2(PNode &pRoot) { if (NULL == pRoot) return; stack<PNode> s; s.push(pRoot); PNode pCur; while (!s.empty()) { pCur = s.top(); s.pop(); while (pCur) { cout << pCur->_data << " "; if (pCur->_pRight) s.push(pCur->_pRight); pCur = pCur->_pLeft; } } } //中序遍历 void _InOrder(PNode pRoot) { if (NULL == pRoot) return; if (pRoot) { _InOrder(pRoot->_pLeft); cout << pRoot->_data << " "; _InOrder(pRoot->_pRight); } } void _InOrder_No(PNode pRoot) { if (NULL == pRoot) return; PNode pCur = pRoot; stack<PNode> s; while (pCur || !s.empty()) { while (pCur) { s.push(pCur); pCur = pCur->_pLeft; } pCur = s.top(); cout << pCur->_data << " "; s.pop(); pCur = pCur->_pRight; } } //后序遍历 void _PostOrder(PNode pRoot) { if (NULL == pRoot) return; if (pRoot) { _PostOrder(pRoot->_pLeft); _PostOrder(pRoot->_pRight); cout << pRoot->_data << " "; } } void _PostOrder_No1(PNode pRoot) { if (NULL == pRoot) return; PNode pCur = pRoot; PNode pTop = NULL; PNode Prev = NULL; stack<PNode> s; while (pCur||!s.empty()) { //左子树入栈 while (pCur) { s.push(pCur); pCur = pCur->_pLeft; } //左子树入栈之后,取栈顶元素 pTop = s.top(); //判断栈顶元素是否有右子树 //右子树不存在,且右子树没有被访问 if (NULL == pTop->_pRight || Prev == pTop->_pRight) { //访问并弹出 cout << pTop->_data << " "; Prev = pTop; s.pop(); } else pCur = pTop->_pRight; } } void _PostOrder_No2(PNode pRoot) { if (NULL == pRoot) return; PNode pCur = pRoot; PNode Prev = NULL; stack<PNode> s; while (pCur || !s.empty()) { //左子树入栈 //这块pCur != Prev改变了pCur的指向,因此是为了防止循环入栈 while (pCur&&pCur != Prev) { s.push(pCur); pCur = pCur->_pLeft; } //这样防止形成死循环 if (s.empty()) return; //左子树入栈之后,取栈顶元素 pCur = s.top(); //判断栈顶元素是否有右子树 //右子树不存在,且右子树没有被访问 if (NULL == pCur->_pRight || Prev == pCur->_pRight) { //访问并弹出 cout << pCur->_data << " "; Prev = pCur; s.pop(); } else pCur = pCur->_pRight; } } //利用后序遍历 void _DestroyBinTree(PNode pRoot) { if (pRoot) { //销毁左子树 _DestroyBinTree(pRoot->_pLeft); //销毁右子树 _DestroyBinTree(pRoot->_pRight); //销毁根节点 delete pRoot; pRoot = NULL; } } 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 _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); } }private: PNode _pRoot;};void Test(){ /*char array[] = "abc###de##f";*/ char array[] = "ab##c"; BinTree<char> bt1(array, strlen(array), '#'); //bt1.PreOrder(); //bt1.Preorder_No1(); //bt1.Preorder_No2(); //bt1.LevelOrder(); //bt1.InOrder(); //bt1.InOrder_No(); bt1.PostOrder(); bt1.Mirror(); bt1.Mirror_No(); bt1.PostOrder_No1(); bt1.PostOrder_No2(); bool s1 = bt1.IsCompleteTree1(); if (s1) { cout << "是完全二叉树" << endl; } else { cout << "不是完全二叉树" << endl; } bool s2 = bt1.IsCompleteTree(); if (s2) { cout << "是完全二叉树" << endl; } else { cout << "不是完全二叉树" << endl; } cout << "叶子结点的个数:" << bt1.GetLeefCount() << endl; cout << "二叉树结点的个数:" << bt1.Size() << endl; cout << "二叉树的高度:" << bt1.Height() << endl; BinTreeNode<char>* pCur1 = bt1.Find('a'); if (pCur1) cout << "找到了" << pCur1->_data << endl; else { cout << "没找到" << endl; } BinTreeNode<char>* pCur2 = bt1.RightChild(bt1.Find('b')); if (pCur2) cout << "找到了" << pCur2->_data << endl; else { cout << "没找到" << endl; } BinTreeNode<char>* pCur3 = bt1.LeftChild(bt1.Find('b')); if (pCur3) cout << "找到了" << pCur3->_data << endl; else { cout << "没找到" << endl; } cout << "第K层的结点个数为:" << bt1.GetKLevelCount(3) << endl; BinTree<char> bt2(bt1); //bt2.PreOrder(); //bt2.InOrder(); //bt2.PostOrder(); BinTree<char> bt3; //bt3 = bt1; //bt3.PreOrder();}int main(){ Test(); system("pause"); return 0;}
- 二叉树面试题(一)
- 二叉树面试题(一) 重建二叉树
- 二叉树相关的面试题<一>
- 二叉树的面试题(一)
- 二叉树面试题汇总(一)
- 二叉树面试题(一)---判断两个二叉树结构是否相同
- 二叉树面试题
- 【面试题】-二叉树
- 二叉树面试题
- 二叉树 面试题
- 二叉树面试题
- 二叉树面试题
- 二叉树面试题
- 【面试题】二叉树
- 【面试题】二叉树
- 二叉树面试题
- 二叉树面试题
- 二叉树面试题
- [Linux移植一]ubuntu搭建NFS
- MySQL学习笔记
- 机器学习之文本分类-神经网络TensorFlow实现(一)
- 团体程序设计天梯赛-练习集 L1-011. A-B
- Ubuntu安装MySQL及遇到的问题解决方案 xwj
- 二叉树面试题(一)
- <script></script>
- C++ STL中sort简单理解
- 机器学习实战笔记-利用SVD简化数据
- Linux安装
- Ubuntu16.04从零开始配置QT+OPEN CV3.2+CONTRIB+CUDA8.0+CUDNN5.1+TENSORFLOW
- 【Scikit-Learn 中文文档】17 概率校准
- JavaScript--变量与常用属性
- 如何实现培训课程微信预约