数据结构——二叉树的基本操作
来源:互联网 发布:java redis 获取list 编辑:程序博客网 时间:2024/05/04 10:19
二叉树节点结构
template<class T>struct BinaryTreeNode{ BinaryTreeNode(const T& data) :_data(data) ,_pLeft(NULL) ,_pRight(NULL) {} T _data; BinaryTreeNode<T>* _pLeft; BinaryTreeNode<T>* _pRight;};
二叉树的构造
template<class T>class BinaryTree{ typedef BinaryTreeNode<T> Node;public: //构造函数 BinaryTree() :_pRoot(NULL) {} BinaryTree(const T array[], size_t size, const T& invalid) { size_t index = 0; _CreateTree(_pRoot, array, size, index, invalid); } //拷贝构造函数 BinaryTree(const BinaryTree<T>& t) { _pRoot = _CopyBinaryTree(t._pRoot ); } //赋值运算符重载 BinaryTree<T>& operator=(const BinaryTree<T>& t) { //先销毁当前对象,再拷贝 _DestroyTree(t._pRoot ); _CopyBinaryTree(t._pRoot ); } ~BinaryTree() { _DestroyTree(_pRoot); } private: void _CreateTree(Node*& pRoot, const T array[], size_t size, size_t& index, const T& invalid) { if(index < size&&array[index] != invalid) { pRoot = new Node(array[index]); _CreateTree(pRoot->_pLeft ,array,size,++index,invalid); _CreateTree(pRoot->_pRight ,array,size,++index,invalid); } } Node* _CopyBinaryTree(Node* pRoot) { if(NULL != pRoot) { Node* pNew = new Node(pRoot->_data); pNew->_pLeft = _CopyBinaryTree(pRoot->_pLeft ); pNew->_pRight = _CopyBinaryTree(pRoot->_pRight ); return pNew; } return NULL; } void _DestroyTree(Node* pRoot) { if(pRoot) { _DestroyTree(pRoot->_pLeft ); _DestroyTree(pRoot->_pRight ); delete pRoot; pRoot = NULL; } }private: BinaryTreeNode<T>* _pRoot;};
二叉树遍历——递归
public: // 先序遍历——递归 void PreOrder() { cout<<"PreOrder()"<<endl; _PreOrder(_pRoot); cout<<endl; } // 中序遍历——递归 void InOrder() { cout<<"InOrder()"<<endl; _InOrder(_pRoot); cout<<endl; } // 后续遍历——递归 void PostOrder() { cout<<"PostOrder()"<<endl; _PostOrder(_pRoot); cout<<endl; }private: void _PreOrder(Node* pRoot) { if(pRoot) { cout<<pRoot->_data <<" "; _PreOrder(pRoot->_pLeft ); _PreOrder(pRoot->_pRight ); } } void _InOrder(Node* pRoot) { if(pRoot) { _InOrder(pRoot->_pLeft ); cout<<pRoot->_data <<" "; _InOrder(pRoot->_pRight ); } } void _PostOrder(Node* pRoot) { if(pRoot) { _PostOrder(pRoot->_pLeft ); _PostOrder(pRoot->_pRight ); cout<<pRoot->_data <<" "; } }
二叉树遍历——非递归
//先序遍历 void _PreOrder_Nor(Node* pRoot) { if(pRoot) { stack<Node*> s; Node* pCur = pRoot; s.push(pCur); 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 _InOrder_Nor(Node* pRoot) { stack<Node*> s; Node* 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 ; //while(NULL == pCur->_pRight ) //{ // pCur = s.top(); // cout<<pCur->_data <<" "; // s.pop(); //} //pCur = pCur->_pRight ; } }//后序遍历 void _PostOrder_Nor(Node* pRoot) { stack<Node*> s; Node* pCur = pRoot;//指向根节点 Node* pPre = NULL;//指向已经访问过的节点 Node* pTop = NULL;//指向栈顶节点 while(pCur || !s.empty()) { while(pCur) { s.push(pCur); pCur = pCur->_pLeft ; } pTop = s.top(); //当节点右子树为空或当前右节点已经访问过,则对该节点进行访问 if(pTop->_pRight == NULL || pPre == pTop->_pRight ) { cout<<pTop->_data <<" "; pPre = pTop; s.pop(); } //转换为子问题 else pCur = pTop->_pRight ; //注意是pCur是指向栈顶节点的右节点 } }
二叉树层序遍历
// 层序遍历 void LevelOrder() { cout<<" LevelOrder()"<<endl; queue<Node*> q;//申请一个保存二叉树节点的队列 Node* pCur = NULL; if(NULL != _pRoot) { q.push (_pRoot); while(!q.empty ()) { pCur = q.front (); cout<<pCur->_data <<" "; if(pCur->_pLeft ) q.push (pCur->_pLeft ); if(pCur->_pRight ) q.push (pCur->_pRight ); q.pop (); } } cout<<endl; }
二叉树面试题
求镜像二叉树
public: //求某一二叉树的镜像——递归 void GetBinaryMirror() { _GetBinaryMirror(_pRoot); } //求某一二叉树的镜像——非递归 void GetBinaryMirror_Nor() { _GetBinaryMirror_Nor(_pRoot); } void _GetBinaryMirror(Node* pRoot) { if(pRoot) { std::swap (pRoot->_pLeft ,pRoot->_pRight ); _GetBinaryMirror(pRoot->_pLeft ); _GetBinaryMirror(pRoot->_pRight ); } }private: void _GetBinaryMirror_Nor(Node* pRoot) { queue<Node*> q; q.push(pRoot); while(!q.empty()) { Node* pCur = q.front(); std::swap (pCur->_pLeft ,pCur->_pRight ); if(pCur->_pLeft ) q.push(pCur->_pLeft ); if(pCur->_pRight ) q.push(pCur->_pRight ); q.pop(); } }
判断一棵树是不是完全二叉树
//判断一颗树是否为完全二叉树 bool IsCompleteBinaryTree() { bool flag = true;//判断一棵子树是否为一棵二叉树的标记 queue<Node*> q;//运用队列进行层序遍历 q.push(_pRoot); while(!q.empty()) { Node* pCur = q.front(); q.pop(); //如果队首元素的左子树为空将标记置为false如果层序遍历后面的节点还有子树说明不是 if(NULL == pCur->_pLeft ) flag = false; else { //如果falg为假,说明之前已经有节点的孩子为空,又因当前节点的左孩子不为空,说明不是 if(flag == false) return false; q.push(pCur->_pLeft ); } //如果队首元素的右树为空,将标记置为false如果层序遍历后面的节点还有子树,说明不是 if(NULL == pCur->_pRight ) flag = false; else { //如果flag为假说明之前已经有节点的孩子为空,又因当前节点的右孩子不为空说明不是 if(flag == false) return false; q.push(pCur->_pRight ); } } return true; }
public: //找双亲节点 Node* GetParent(T& value) { Node* x = Find(value); return _GetParent(_pRoot,x); }private: Node* _GetParent(Node* pRoot,Node* x) { if(pRoot == NULL||x == NULL||pRoot == x) return NULL; if(x == pRoot->_pLeft || x == pRoot->_pRight ) return pRoot; Node* pLeft = _GetParent(pRoot->_pLeft ,x); Node* pRight = _GetParent(pRoot->_pRight ,x); }
public: //判断某节点是否存在 Node* Find(const T& value) { return _Find(_pRoot,value); }private: Node* _Find(Node* pRoot,const T& value) { if(NULL == pRoot) return NULL; if(pRoot->_data == value) return pRoot; Node* pCur = _Find(pRoot->_pLeft ,value); if(pCur) return pCur; return _Find(pRoot->_pRight ,value); }
//获得某节点的左孩子 Node* GetLeftChild(Node* pCur) { return (NULL == pCur)?NULL:pCur->_pLeft ; } //获得某节点的右孩子 Node* GetRightChild(Node* pCur) { return (NULL == pCur)?NULL:pCur->_pRight ; }
//计算二叉树的高度 size_t Height() { return _Height(_pRoot); } size_t _Height(Node* pRoot) { if(NULL == pRoot) return 0; if(NULL == pRoot->_pLeft && NULL == pRoot->_pRight ) return 1; size_t hLeft = _Height(pRoot->_pLeft ); size_t hRight = _Height(pRoot->_pRight ); return hLeft>hRight?hLeft+1:hRight+1; }
//计算叶子节点的个数 size_t GetLeafNode() { return _GetLeafNode(_pRoot); } size_t _GetLeafNode(Node* pRoot) { if(NULL == pRoot) return 0; if(NULL == pRoot->_pLeft && NULL == pRoot->_pRight ) return 1; return _GetLeafNode(pRoot->_pLeft )+_GetLeafNode(pRoot->_pRight ); }
//计算第K层的节点数 size_t GetKLevelNode(size_t k) { return _GetKLevelNode(_pRoot, k); } size_t _GetKLevelNode(Node* pRoot,size_t k) { if(NULL == pRoot && k<1 && k>_Height(pRoot)) return 0; if(k == 1) return 1; size_t kLeft = _GetKLevelNode(pRoot->_pLeft ,k-1); size_t kRight = _GetKLevelNode(pRoot->_pRight ,k-1); return kLeft + kRight; }
阅读全文
0 0
- 数据结构—二叉树基本操作
- 数据结构——二叉树的基本操作
- 数据结构实验2——二叉树的基本操作
- 数据结构复习——二叉树的几个基本操作
- 数据结构——二叉树的基本操作
- 数据结构——二叉树的基本操作
- 数据结构复习整理——二叉树的基本操作
- 数据结构 — 二叉树的基本操作(递归实现)
- 数据结构 — 二叉树的基本操作实现(递归算法)
- 数据结构之二叉树的基本操作
- 【数据结构】二叉树的基本操作
- (数据结构)二叉树的基本操作
- 【数据结构笔记】二叉树的基本操作
- 数据结构-二叉树的基本操作
- 数据结构->二叉树的基本操作
- 数据结构——二叉树及其基本操作
- 数据结构——二叉树的操作
- 数据结构——树(2)——二叉堆的基本操作原理
- java学习(一)----正则表达式
- Mysql主从复制
- 编辑距离的一些理解
- 使用 Office 365 PowerShell 管理用户帐户和许可证(十二)Configure user account properties with Office 365 PowerShel
- kibana3 from source
- 数据结构——二叉树的基本操作
- MHA中send_report脚本(使用Email::Simple模块)
- 【Shader】热扭曲实现刀光特效
- Lua与OC相互调用
- C#获取本机IP地址,测试IP地址是否能够Ping通
- 多线程(1)
- $.map()的用法
- 电压比较器工作原理及应用
- nginx学习记录02-配置说明