二叉树常见的面试题(1)
来源:互联网 发布:影音后期制作软件大全 编辑:程序博客网 时间:2024/05/19 14:50
#pragma once#include<iostream>#include<windows.h>#include<string.h>#include<queue>#include<stack>using namespace std;// 孩子表示法template<class T>struct BinaryTreeNode{ BinaryTreeNode(const T& value) : _value(value) , _pLeft(NULL) , _pRight(NULL) {} T _value; BinaryTreeNode<T>* _pLeft; // 左孩子 BinaryTreeNode<T>* _pRight; // 右孩子};//创建(遍历)二叉树的时间复杂度O(N)template<class T>class BinaryTree{ typedef BinaryTreeNode<T> Node;public: BinaryTree() : _pRoot(NULL) {} BinaryTree(const T arr[], size_t size, const T& invalid) { size_t index = 0; _CreateBinaryTree(_pRoot, arr, size, index, invalid); } BinaryTree(const BinaryTree<T>& bt) { _pRoot = _CopyBirnaryTree(bt._pRoot); } BinaryTree<T>& operator=(const BinaryTree<T>& bt) { if (this != &bt) { _DestroyBinaryTree(_pRoot); _pRoot=_CopyBirnaryTree(bt._pRoot); } return *this; } ~BinaryTree() { _DestroyBinaryTree(_pRoot); } /////////////////////////////////////////////////////////////// void PreOrder() { cout << "PreOrder:" << endl; _PreOrder(_pRoot); cout << endl; } void PreOrder_Nor() { cout << "PreOrder_Nor:" << endl; _PreOrder_Nor(_pRoot); cout << endl; } void InOrder() { cout << "InOrder:" << endl; _InOrder(_pRoot); cout << endl; } void InOrder_Nor() { cout << "InOrder_Nor:" << endl; _InOrder_Nor(_pRoot); cout << endl; } void PostOrder() { cout << "PostOrder:" << endl; _PostOrder(_pRoot); cout << endl; } void PostOrder_Nor() { cout << "PostOrder_Nor:" << endl; _PostOrder_Nor(_pRoot); cout << endl; } void LevelOrder()//******考点********队列*** { cout << "LevelOrde:" << endl; _LevelOrder(_pRoot); cout << endl; } Node* Find(const T& value) { return _Find(_pRoot, value); } //二叉树中和为某一值的路径 void FindPath(size_t WantSum) { size_t Cursum = 0; vector<int>path; _FindPath(_pRoot, WantSum, path, Cursum); } Node* Parent(Node* pCur) { return _Parent(_pRoot, pCur); } Node* GetLeftChild(Node* pCur) { return (pCur == NULL) ? NULL : pCur->_pLeft; } Node* GetRightChild(Node* pCur) { return (pCur == NULL) ? NULL : pCur->_pRight; } size_t Height() { return _Height(_pRoot); } size_t GetLeefCount() { return _GetLeefCount(_pRoot); } size_t GetKLevelCount(size_t k) { return _GetKLevelCount(_pRoot, k); } void BinaryMirror_Nor() { return _BinaryMirror_Nor(); } void BinaryMirror() { return _BinaryMirror(_pRoot); }private: // 根—左—右 —>构造二叉树 void _CreateBinaryTree(Node* &pRoot, const T arr[], size_t size, size_t& index, const T& invalid) { if (index < size&&arr[index] != invalid)//顺序不能颠倒,防止越界访问 { //创建根节点 pRoot = new Node(arr[index]); //创建左孩子节点 _CreateBinaryTree(pRoot->_pLeft, arr, size, ++index, invalid); //创建右孩子节点(看不见右孩子创建节点过程) _CreateBinaryTree(pRoot->_pRight, arr, size, ++index, invalid); } } // pRoot-->被拷贝树的根节点 Node* _CopyBirnaryTree(Node* pRoot) { Node* pNewRoot = NULL; if (pRoot) { pNewRoot = new Node(pRoot[0]);//拷贝根节点 pNewRoot->_pLeft = _CopyBirnaryTree(pRoot->_pLeft); //拷贝左子树 pNewRoot->_pRight = _CopyBirnaryTree(pRoot->_pRight);//拷右左子树 } return pNewRoot; } void _DestroyBinaryTree(Node*& pRoot) { if (pRoot) { _DestroyBinaryTree(pRoot->_pLeft); _DestroyBinaryTree(pRoot->_pRight); delete pRoot; pRoot = NULL; } } //////////////////////////////////////////////////////////////// //前序遍历递归 // 前序:访问根节点--->访问根节点的左子树--->访问根节点的右子树 void _PreOrder(Node* pRoot) { if (pRoot) { cout << pRoot->_value << " "; _PreOrder(pRoot->_pLeft); _PreOrder(pRoot->_pRight); } } //前序遍历非递归 void _PreOrder_Nor(Node*pRoot) { if (NULL == pRoot) return; stack<Node*>s; s.push(pRoot); while (!s.empty()) { Node*pCur = s.top(); cout << pCur->_value << " "; s.pop(); if (pCur->_pRight) s.push(pCur->_pRight); if (pCur->_pLeft) s.push(pCur->_pLeft); } } //中序遍历递归 void _InOrder(Node* pRoot) { if (pRoot) { _InOrder(pRoot->_pLeft); cout << pRoot->_value << " "; _InOrder(pRoot->_pRight); } } //中序遍历非递归 void _InOrder_Nor(Node*pRoot) { if (NULL == pRoot) return; stack<Node*>s; Node*pCur = pRoot; while (pCur || !s.empty()) { while (pCur) { // 找到最左边的孩子,并把所经过路径的结点保存下来 s.push(pCur); pCur = pCur->_pLeft; } //出了内层循环,pCur为空,栈顶元素为最左边的孩子 pCur = s.top(); cout << pCur->_value << " "; s.pop(); pCur = pCur->_pRight; } } // 后序遍历:遍历根的左子树-->遍历根的右子树-->遍历根节点 void _PostOrder(Node* pRoot) { if (pRoot) { _PostOrder(pRoot->_pLeft); _PostOrder(pRoot->_pRight); cout << pRoot->_value << " "; } } //后序遍历非递归 void _PostOrder_Nor(Node*pRoot) { if (NULL == pRoot) return; stack<Node*>s; Node*pCur = pRoot; Node*Prev = NULL;//保存上次入栈的结点 while (pCur || !s.empty()) { while (pCur) { // 找到最左边的孩子,并把所经过路径的结点保存下来 s.push(pCur); pCur = pCur->_pLeft; } Node*pTop = s.top(); if (NULL == pTop->_pRight || Prev == pTop->_pRight)//没有Prev == pTop->_pRight会4256666666......死循环下去 { cout << pTop->_value << " "; Prev = pTop; //保存上次入栈的结点 s.pop(); } else { pCur = pTop;//pCur在while出来之后为NULL,所以要更新pCur的值,少了这句,崩溃 pCur = pCur->_pRight; } } } // 层序遍历 void _LevelOrder(Node*pRoot)//******考点********队列*** { if (NULL == pRoot) return; queue<Node*>q; q.push(pRoot);//保存的是结点的地址,地址出了队列,但是树并没有改变 while (!q.empty()) { Node*pcur = q.front(); cout << pcur->_value << " "; if (pcur->_pLeft)//左不为空入队列 { q.push(pcur->_pLeft); } if (pcur->_pRight)//右不为空入队列 { q.push(pcur->_pRight); } q.pop(); } cout << endl; } //二叉树中和为某一值的路径 void _FindPath(Node*pRoot, size_t WantSum, vector<int>&path, size_t CurSum) { CurSum += pRoot->_value; path.push_back(pRoot->_value); //如果是叶子结点,并且路径上结点的和等于输入的值,打印这条路径 if (CurSum == WantSum&&NULL == pRoot->_pLeft&&NULL == pRoot->_pRight) { cout << WantSum << "path is found:" << endl; vector<int>::iterator it = path.begin(); while (!path.empty() && it != path.end()) { cout << *it << " "; it++; } cout << endl; } if (pRoot->_pLeft) { _FindPath(pRoot->_pLeft, WantSum, path, CurSum); } if (pRoot->_pRight) { _FindPath(pRoot->_pRight, WantSum, path, CurSum); } //在返回父节点之前,在路径上删除当前节点 path.pop_back(); } //树中查找一个节点 Node* _Find(Node* pRoot, const T& value) { Node*pCur = NULL; if (NULL == pRoot) return NULL; if (pRoot->_value == value) { return pRoot; } pCur = _Find(pRoot->_pLeft, value); if (NULL!=pCur) return pCur; return _Find(pRoot->_pRight, value); } //求一个节点的双亲 Node* _Parent(Node* pRoot, Node* pCur) { if (NULL == pRoot)//树空 return NULL; if (NULL==pRoot->_pLeft&&NULL == pRoot->_pRight)//只有一个节点 return NULL; if (pRoot == pCur) return NULL;//所找结点刚好为根结点 if (pCur == pRoot->_pLeft || pCur == pRoot->_pRight) return pRoot; Node*parent = NULL; parent = _Parent(pRoot->_pLeft, pCur);//从左子树中找 if (NULL != pCur) return pCur; return _Parent(pRoot->_pLeft, pCur);//从右子树中找 } //求二叉树的高度 size_t _Height(Node* pRoot) { if (NULL == pRoot) return 0; if (NULL == pRoot->_pLeft&&NULL == pRoot->_pRight)//一个节点 return 1; size_t Left_Height=_Height(pRoot->_pLeft);//左子树的高度 size_t Right_Height = _Height(pRoot->_pRight);//右子树的高度 return Left_Height > Right_Height ? Left_Height + 1 : Right_Height + 1; } //求叶子节点的个数 size_t _GetLeefCount(Node* pRoot) { if (NULL == pRoot) return 0; if (NULL == pRoot->_pLeft&&NULL == pRoot->_pRight)//一个节点 return 1; size_t Left_LeefCount=_GetLeefCount(pRoot->_pLeft); size_t Right_LeefCount = _GetLeefCount(pRoot->_pRight); return Left_LeefCount + Right_LeefCount; } //求第K层节点的个数 size_t _GetKLevelCount(Node* pRoot, size_t k) { if (NULL == pRoot || k<1)//此处省略了K>Height(_pRoot),因为大于树的 return 0; //高度时返回0 if (k == 1) return 1; size_t LeftKLevelCount=_GetKLevelCount(pRoot->_pLeft, k - 1); size_t RighttKLevelCount = _GetKLevelCount(pRoot->_pRight, k - 1); return LeftKLevelCount + RighttKLevelCount; } //二叉树的镜像—递归 void _BinaryMirror(Node* pRoot) { if (NULL == pRoot) return; swap(pRoot->_pLeft, pRoot->_pRight); _BinaryMirror(pRoot->_pLeft); _BinaryMirror(pRoot->_pRight); } //二叉树的镜像—非递归 void _BinaryMirror_Nor() { if (NULL == _pRoot) return; queue<Node*>q; q.push(_pRoot); while (!q.empty()) { Node*pCur = q.front(); if (pCur) { q.push(pCur->_pLeft); } if (pCur) { q.push(pCur->_pRight); } if (NULL!=pCur)//必须判断 swap(pCur->_pLeft, pCur->_pRight); q.pop(); } }private: Node* _pRoot; // 指向树的根节点};
阅读全文
1 0
- 二叉树的常见面试题(1)
- 二叉树常见的面试题(1)
- 常见的二叉树面试题
- 二叉树的常见面试题总结
- (C++)二叉树中的那些常见的面试题
- 二叉树常见面试题
- 二叉树常见面试题
- 常见的二叉树面试题大汇总(涵盖二叉搜索树)
- 二叉树中的那些常见的面试题
- 二叉树中的那些常见的面试题
- 二叉树中的那些常见的面试题
- 二叉树中的那些常见的面试题
- 二叉树中的那些常见的面试题
- 二叉树中的那些常见的面试题
- 二叉树中的那些常见的面试题
- 二叉树中的那些常见的面试题
- 二叉树中的那些常见的面试题
- 二叉树中的那些常见的面试题
- 非虚方法的调用
- 无数个骂娘的故事告诉你,千万别做技术合伙人!
- python基础知识(3)
- Linux--RH254---unit 2 高级网络配置
- 给定N张扑克牌和一个随机函数,设计一个洗牌算法
- 二叉树常见的面试题(1)
- Linux--RH254---unit 9 apache web服务
- 解决学习tensorflow的LSTM模型中遇到一个版本不兼容问题
- git 使用
- NYOj 264 国王的魔镜
- python模块sys与os还有内置函数
- C和指针 练习 1-5 1-6
- ssm和ssh框架中,oracle数据库,表主键自增如何解决
- cocopods更新失败解决