二叉树的创建和基本操作(递归和非递归)
来源:互联网 发布:淘宝代付可以用微信吗 编辑:程序博客网 时间:2024/06/04 18:03
二叉树的定义在这里不做陈述,我们直接来看看如何实现一个二叉树的创建(c++)
首先定义结点,这里我们呢用结构体来创建
template<typename T>struct BinaryTreeNode //创建孩子二叉树的结点{ BinaryTreeNode(const T& data = T()) :_data(data) , _pLeft(NULL) , _pRight(NULL) {} T _data; BinaryTreeNode* _pLeft; BinaryTreeNode* _pRight;};
定义好结点之后我们就可以来想办法创建一个二叉树类,其中包含二叉树的创建和基本操作
template<typename T>class BinaryTree{ typedef BinaryTreeNode<T> Node;public: BinaryTree() : _pRoot() {} /***********用函数封装来做************/ BinaryTree(const T* array, size_t size, const T& invalid) //构造函数构造二叉树 { size_t index = 0; _pRoot = CreatTree(array, size, index, invalid); } BinaryTree(const BinaryTree<T>& b) //拷贝构造一个相同的二叉树 { _pRoot = Copy(b._pRoot); } BinaryTree& operator=(BinaryTree<T>& b) //重载= { if (this != &b) //防止自己给自己赋值 { BinaryTree<T> tem(b); std::swap(_pRoot, tem._pRoot); } return *this; } ~BinaryTree() //析构函数释放树 { Destory(_pRoot); } size_t _Leaf() //求叶子结点个数 { return Leaf(_pRoot); } size_t _Size() //求结点个数 { return Size(_pRoot); } size_t _Depth() //求树的深度 { return Depth(_pRoot); } void _PreOder() //先序遍历 { PreOder(_pRoot); cout << endl; } void _InOder() //中序遍历 { InOder(_pRoot); cout << endl; } void _BackOder() //后序遍历 { BackOder(_pRoot); cout << endl; }protected: Node* _pRoot;}
创建好这个二叉树类之后我们来将其中的功能进行相应的实现(这里我将所有的函数实现都已private的形式写在了类内部)
··········创建二叉树/*先序递归创建二叉树*/ Node* CreatTree(const T* array, size_t size, size_t& index, const T& invalid) { assert(array); Node* pRoot = NULL; if (index < size&&array[index] != invalid) { pRoot = new Node(array[index]); pRoot->_pLeft = CreatTree(array, size, ++index, invalid); pRoot->_pRight = CreatTree(array, size, ++index, invalid); } return pRoot; }/*非递归创建二叉树*/ Node *CreatTree(const T* a, size_t size, size_t index, const T& invalid) { stack<Node*> s; Node* pRoot = new Node(a[index++]); int flag = 1; //flag =1创建左孩子,=2创建右孩子,=3出栈 s.push(pRoot); Node *pPre = NULL; Node *pCur = NULL; while (index<size) { if (flag == 1) //创建左孩子 { if (a[index] == invalid) //如果左孩子为空,则flag=2创建右孩子 { flag = 2; } else { pCur = new Node(a[index]); pPre = s.top(); pPre->_pLeft = pCur; //链接到左指针上 s.push(pCur); //将新节点压入栈中 } } else if (flag == 2) //flag=2,创建右孩子 { if (a[index] == invalid) //如果右孩子为空,则flag=3准备出栈 { flag = 3; } else { pCur = new Node(a[index]); pPre = s.top(); pPre->_pRight = pCur; //链接到左指针上 s.push(pCur); //将新节点压入栈中 flag = 1; //再创建新结点的左孩子 } } else { if (!s.empty()) { pPre = s.top(); s.pop(); } //如果已经出栈的元素是当前栈顶的右孩子,则表示这个结点的左右子树已经创建完毕,则一直出栈 while (!s.empty() && s.top()->_pRight == pPre) { pPre = s.top(); s.pop(); } flag = 2; index--; } index++; } return pRoot; }··········先序遍历/*递归先序遍历*/ void PreOder(Node* pRoot) { Node* pCur = pRoot; if (pCur) { cout << pCur->_data << " "; PreOder(pCur->_pLeft); PreOder(pCur->_pRight); } }/*非递归先序遍历*/ void PreOder(Node* _pRoot) { assert(_pRoot); Node *pRoot = _pRoot; stack<Node*> s; s.push(pRoot); int flag = 1; Node *pCur = NULL; while (!s.empty()) { pCur = s.top(); if (flag == 1) //遍历左子树 { if (pCur->_pLeft == NULL) //如果左子树为空,则flag=2 { flag = 2; } else { cout << pCur->_Data << " "; //先序输出,先输出根结点 s.push(pCur->_pLeft); } } else if (flag == 2) { if (pCur->_pRight == NULL) { flag = 3; } else { s.push(pCur->_pRight); flag = 1; } } else { Node *pPre = NULL; if (!s.empty()) { pPre = s.top(); s.pop(); } pCur = pPre; while (!s.empty() && s.top()->_pRight == pPre) //将输出过的结点出栈 { pPre = s.top(); s.pop(); } if (!s.empty()) //输出右子树的叶子节点 { cout << pCur->_Data << " "; } flag = 2; } } cout << endl; }·········中序遍历/*递归中序遍历*/ void InOder(Node* pRoot) { Node* pCur = pRoot; if (pCur) { InOder(pCur->_pLeft); cout << pCur->_data << " "; InOder(pCur->_pRight); } }/*非递归中序遍历*/ void InOder(Node* _pRoot) { assert(_pRoot); Node *pRoot = _pRoot; stack<Node*> s; s.push(pRoot); int flag = 1; while (!s.empty()) { Node *pCur = s.top(); if (flag == 1) //先遍历左子树 { if (pCur->_pLeft == NULL) { flag = 2; } else { s.push(pCur->_pLeft); } } else if (flag == 2) //遍历右子树 { if (pCur->_pRight == NULL) { flag = 3; } else { cout << pCur->_Data << " "; //输出右子树的跟结点 s.push(pCur->_pRight); flag = 1; } } else { Node* pPre = NULL; if (!s.empty()) { pPre = s.top(); s.pop(); } cout << pPre->_Data << " "; //输出左子树结点和左子树的根结点 while (!s.empty() && s.top()->_pRight == pPre) { pPre = s.top(); s.pop(); } flag = 2; } } cout << endl; }········后序遍历/*递归后序遍历*/ void BackOder(Node* pRoot) { Node* pCur = pRoot; if (pCur) { BackOder(pCur->_pLeft); BackOder(pCur->_pRight); cout << pCur->_data << " "; } }/*非递归后序遍历*/ void BackOder(Node* _pRoot) { assert(_pRoot); Node *pRoot = _pRoot; stack<Node*> s; int flag = 1; //=1遍历左子树,=2 遍历右子树,=3 输出结点 s.push(pRoot); //根节点入栈 Node *pCur = NULL; while (!s.empty()) { pCur = s.top(); if (flag == 1) //遍历左子树 { if (pCur->_pLeft == NULL) //如果左子树为空,则flag=2,准备遍历右子树 { flag = 2; } else { s.push(pCur->_pLeft); } } else if (flag == 2) //遍历右子树 { if (pCur->_pRight == NULL) //右子树为空,准备输出结点 { flag = 3; } else { s.push(pCur->_pRight); flag = 1; //遍历当前结点的左子树 } } else { Node *pPre = NULL; if (!s.empty()) { pPre = s.top(); //保存当前栈顶元素 s.pop(); //抛出栈顶元素 } cout << pPre->_Data << " "; //输出结点的信息 //如果当前栈顶元素的右子树是pPre,则抛出pPre之后按照后序也要抛出栈顶元素 while (!s.empty() && s.top()->_pRight == pPre) { pPre = s.top(); //保存当前栈顶元素 s.pop(); //抛出栈顶元素 cout << pPre->_Data << " "; //输出结点的信息 } flag = 2; } } cout << endl; }········求叶子结点个数/*递归*/ size_t Leaf(Node* pRoot) { Node* pCur = pRoot; if (NULL == pCur) return 0; if (pCur->_pLeft == NULL&&pCur->_pRight == NULL) //如果左右子树都为空,则返回1 return 1; return Leaf(pCur->_pLeft) + Leaf(pCur->_pRight); }/*非递归*/ size_t Leaf(Node* pRoot) { size_t index = 0; Node* pCur = pRoot; stack<Node*> s; while (pCur || !s.empty()) { while (pCur) { //如果左右子树都为空,则为叶子结点 if (pCur->_pLeft == NULL&&pCur->_pRight == NULL) index++; s.push(pCur); pCur = pCur->_pLeft; } Node* pPre = s.top(); s.pop(); pCur = pPre ->_pRight; } return index; }·········求结点个数/*递归*/ size_t Size(Node* pRoot) { if (pRoot == NULL) return 0; return 1 + Size(pRoot->_pLeft) + Size(pRoot->_pRight); }/*非递归*/ size_t Size(Node* pRoot) { size_t index = 0; Node* pCur = pRoot; stack<Node*> s; while (pCur || !s.empty()) { while (pCur) { index++; //遍历一个结点就让count++ s.push(pCur); pCur = pCur->_pLeft; } Node * top = s.top(); s.pop(); pCur = top->_pRight; } return index; }········树的深度/*递归*/ size_t Depth(Node* pRoot) { Node* pCur = pRoot; if (NULL == pCur) return 0; return 1 + (Depth(pCur->_pLeft) > Depth(pCur->_pRight) ? Depth(pCur->_pLeft) : Depth(pCur->_pRight)); }/*非递归*/ size_t Depth(Node* pRoot) { if (pRoot == NULL) return 0; queue<Node*> q; size_t deep = 0; size_t NodeNum = 1; //统计有多少数据入过队 size_t LeveLast = 1; //标记正在访问的这层的最后一个数据的序号 size_t VisitNum = 0; //统计已经出队的数据的个数 q.push(pRoot); while (!q.empty()) { Node* pCur = q.front(); q.pop(); VisitNum++; if (NULL != pCur->_pLeft) { q.push(pCur->_pLeft); NodeNum++; } if (NULL != pCur->_pRight) { q.push(pCur->_pRight); NodeNum++; } //如果以出队的个数等于这一层的最后一个数据的序号 if (LeveLast == VisitNum) { deep++; //访问完一层就让深度加一 LeveLast = NodeNum; //更新到下一层的最后一个数据的位置 } } return deep; }
创建好之后让我么来测试一下,首先测试递归版本的二叉树
测试代码如下
void FunTest(){ int array[] = { 1, 2, 3, '#', 4, '#', '#', 5, 6, '#', '#', 7 }; BinaryTree<int> t(array, sizeof(array) / sizeof(array[0]), '#'); cout << t._Leaf() << endl; cout << t._Size() << endl; cout << t._Depth() << endl; t._PreOder(); t._InOder(); t._BackOder();}int main(){ FunTest(); return 0;}
输出结果为
接下来是非递归版本的二叉树
测试代码如下
void FunTest(){ int arr[] = { 1, 2, 3, '#', '#', 4, '#', '#', 5, 6 }; BinaryTree<int> t(arr, sizeof(arr) / sizeof(arr[0]), '#'); t._PrevOder(); t._InOder(); t._BackOder(); cout << t._Leaf() << endl; cout << t._Size() << endl; cout << t._Depth() << endl;}int main(){ FunTest(); system("pause"); return 0;}
输出结果为
以上就是二叉树的创建及基本操作
0 0
- 二叉树的创建和基本操作(递归和非递归)
- 二叉树的基本操作(创建、递归和非递归遍历、求深度、求叶子数)
- 二叉树基本操作递归和非递归方法
- 二叉树的基本操作实现(递归和非递归)
- 二叉树创建、遍历的递归和非递归实现
- 二叉树的创建及递归和非递归遍历
- 二叉树的创建,递归和非递归遍历
- 二叉树的创建和递归与非递归遍历
- C语言实现二叉树的递归和非递归算法的基本操作
- 二叉树的递归和非递归
- 二叉树的递归和非递归
- 二叉树的建立和基本操作(递归实现)
- C++递归创建、非递归遍历二叉树的基本操作
- 二叉树的遍历(递归和非递归)
- 二叉树的遍历(递归和非递归)
- 二叉树的建立和遍历(递归、非递归)
- 二叉树的遍历(非递归和递归实现)
- 二叉树的先序中序后序遍历 (递归和非递归)
- mac top内存 cpu
- 创建自定义JSP模板
- map
- Unsafe与CAS
- python request库 百度360关键词搜索提交
- 二叉树的创建和基本操作(递归和非递归)
- multiset 的排序规则
- HTTP Status 500
- cropperjs在.vue中的使用
- FPGA:下一代机器人感知处理器
- set 容器
- 大白话讲解SVM
- [设计模式]责任链模式(Chain of Responsibility)
- Java关键字final、static使用总结