[BinaryTree] 二叉树类的实现
来源:互联网 发布:coach淘宝代购 编辑:程序博客网 时间:2024/06/02 05:54
二叉树结点的抽象数据类型:
1 template<class T> 2 class BinaryTreeNode 3 { 4 friend class BinaryTree<T>; 5 private: 6 T element; //结点的数据域 7 BinaryTreeNode<T>* LeftChild; //结点的左孩子结点 8 BinaryTreeNode<T>* RightChild; //结点的右孩子结点 9 public:10 BinaryTreeNode();11 BinaryTreeNode(const T& ele);12 BinaryTreeNode(const T& ele, BinaryTreeNode<T>* l, BinaryTreeNode<T>* r);13 bool isLeaf() const; //判断该结点是否是叶子结点,若是,则返回true14 };
二叉树结点函数功能实现:
1 template<class T> 2 BinaryTreeNode<T>::BinaryTreeNode() 3 { 4 LeftChild = RightChild = NULL; 5 } 6 template<class T> 7 BinaryTreeNode<T>::BinaryTreeNode(const T& ele) 8 { 9 element = ele;10 LeftChild = RightChild = NULL;11 }12 template<class T>13 BinaryTreeNode<T>::BinaryTreeNode(const T& ele, BinaryTreeNode<T>* l, BinaryTreeNode<T>* r)14 {15 element = ele;16 LeftChild = l;17 RightChild = r;18 }19 template<class T>20 bool BinaryTreeNode<T>::isLeaf() const21 {22 if (LeftChild == NULL && RightChild == NULL)23 return true;24 else return false;25 }
二叉树的抽象数据类型:
1 template<class T> 2 class BinaryTree 3 { 4 private: 5 BinaryTreeNode<T>* root; 6 public: 7 BinaryTree(); 8 ~BinaryTree() {} 9 bool IsEmpty() const; //判断二叉树是否为空树10 BinaryTreeNode<T>* getRoot() const; //返回二叉树的根结点11 void breadthFirstOrder(BinaryTreeNode<T>* root);//广度优先遍历以root为根结点的子树12 void preOrder(BinaryTreeNode<T>* root); //先序遍历以root为根结点的子树13 void inOrder(BinaryTreeNode<T>* root); //中序遍历以root为根结点的子树14 void postOrder(BinaryTreeNode<T>* root); //后序遍历以root为根结点的子树15 void deleteBinaryTree(BinaryTreeNode<T>* root); //删除以root为根结点的子树16 void visit(BinaryTreeNode<T>* pointer); //访问当前结点17 BinaryTreeNode<T>* build_from_pre_and_in(char* preorder, char* inorder, int n);18 //根据前序和中序遍历表达式构造二叉树19 BinaryTreeNode<T>* build_from_post_and_in(char* postorder, char* inorder, int m);20 //根据后序和中序遍历表达式构造二叉树21 int getRootId1(char *preorder, char *inorder, int n); //返回根结点在中序遍历表达式中序号22 int getRootId2(char *postorder, char *inorder, int m); //返回根结点在中序遍历表达式中序号23 };
广度优先遍历(队列):
【思路】根结点入队,队列不空循环,访问队头并出队,左子树不空则入队,右子树不空则入队。
1 template<class T> 2 void BinaryTree<T>::breadthFirstOrder(BinaryTreeNode<T>* root) 3 { 4 queue<BinaryTreeNode<T> *> nodeQueue; 5 BinaryTreeNode<T> * pointer = root; 6 if (pointer) 7 nodeQueue.push(pointer); 8 while (!nodeQueue.empty()) 9 {10 pointer = nodeQueue.front();11 visit(pointer);12 nodeQueue.pop();13 if (pointer->LeftChild)14 nodeQueue.push(pointer->LeftChild);15 if (pointer->RightChild)16 nodeQueue.push(pointer->RightChild);17 }18 }
先序遍历:
【思路】
1.访问当前结点
2.当前结点的右儿子结点非空,则入栈
3.左儿子结点非空,使之作为当前结点,否则弹出栈顶元素,使之作为当前结点
4.反复执行1、2、3,至栈空为止
1 template<class T> 2 void BinaryTree<T>::preOrder(BinaryTreeNode<T>* root) 3 { 4 stack<BinaryTreeNode<T> *> nodeStack; 5 BinaryTreeNode<T> * pointer = root; 6 while (!nodeStack.empty() || pointer) 7 { 8 if (pointer) 9 {10 visit(pointer);11 if (pointer->RightChild != NULL)12 nodeStack.push(pointer->RightChild);13 pointer = pointer->LeftChild;14 }15 else16 {17 pointer = nodeStack.top();18 nodeStack.pop();19 }20 }21 }
中序遍历:
【思路】
1.每遇到一个结点就把它压栈,然后去遍历其左子树
2.遍历完左子树后,从栈顶弹出这个结点并访问之
3.然后遍历该结点的右子树
1 template<class T> 2 void BinaryTree<T>::inOrder(BinaryTreeNode<T>* root) 3 { 4 stack<BinaryTreeNode<T> *> nodeStack; 5 BinaryTreeNode<T> * pointer = root; 6 while (!nodeStack.empty() || pointer) 7 { 8 if (pointer) 9 {10 nodeStack.push(pointer);11 pointer = pointer->LeftChild;12 }13 else14 {15 pointer = nodeStack.top();16 visit(pointer);17 pointer = pointer->RightChild;18 nodeStack.pop();19 }20 }21 }
后序遍历:
【基本思想】
1.每遇到一个结点,先把它推入栈中,去遍历它的左子树
2.遍历完它的左子树后,应继续遍历该结点的右子树
3.遍历完右子树之后,才从栈顶弹出该结点并访问它
【解决方案】
0.将根结点作为当前结点
1.进栈过程:
a.如果当前结点不空且具有左子树,将当前结点压入栈中,否则进入2
b.将当前结点的左子树的根结点设置为当前结点
c.重复 a
2.出栈过程:
a.如果当前结点不空且没有右子树,或者其右子树的根结点已经访问,访问之,否则进入3
b.若栈空,结束,否则取出当前栈顶结点作为当前结点
c.重复 a
3.将当前结点压入栈中
4.将当前结点的右子树的根结点设为当前结点,重复 1
1 template<class T> 2 void BinaryTree<T>::postOrder(BinaryTreeNode<T>* root) 3 { 4 stack<BinaryTreeNode<T> * > nodeStack; 5 BinaryTreeNode<T> *pre = root, *pointer = root; 6 while (pointer) 7 { 8 //入栈过程 9 for (; pointer->LeftChild != NULL; pointer = pointer->LeftChild)10 {11 nodeStack.push(pointer);12 }13 //出栈过程14 while (pointer != NULL && (pointer->RightChild == NULL || pointer->RightChild == pre))15 //当前结点右孩子为空或右孩子刚被访问过,则访问该结点16 {17 visit(pointer);18 pre = pointer;19 if (nodeStack.empty())20 return;21 pointer = nodeStack.top();22 nodeStack.pop();23 }24 //将当前结点压入栈中25 nodeStack.push(pointer);26 //将当前结点的右子树的根结点设为当前结点27 pointer = pointer->RightChild;28 }29 }
删除以root为根结点的子树:
1 template<class T> 2 void BinaryTree<T>::deleteBinaryTree(BinaryTreeNode<T>* root) 3 { 4 if (root->LeftChild != NULL) 5 deleteBinaryTree(root->LeftChild); 6 if (root->RightChild != NULL) 7 deleteBinaryTree(root->RightChild); 8 delete root; 9 root = NULL;10 }
根据前序和中序遍历表达式构造二叉树:
【思路】根据前序序列,找到根结点在中序序列中的位置,递归根结点的左子树序列和右子树序列。
1 template<class T> 2 BinaryTreeNode<T>* BinaryTree<T>::build_from_pre_and_in(char* preorder, char* inorder, int n) 3 { 4 if (n == 0) 5 return NULL; 6 char root_element = preorder[0]; 7 int i = 0; 8 for( ;i < n;i ++) 9 {10 if(root_element == inorder[i])11 break;12 }13 BinaryTreeNode<T>* root = new BinaryTreeNode<T>;14 root->element = root_element;15 root->LeftChild = build_from_pre_and_in(preorder + 1, inorder, i);16 root->RightChild = build_from_pre_and_in(preorder + i + 1, inorder + i + 1, n - i - 1);17 return root;18 }
根据后序和中序遍历表达式构造二叉树:
【思路】根据后序序列,找到根结点在中序序列中的位置,递归根结点的左子树序列和右子树序列。
1 template<class T> 2 BinaryTreeNode<T>* BinaryTree<T>::build_from_post_and_in(char* postorder, char* inorder, int m) 3 { 4 if (m == 0) 5 return NULL; 6 char root_element = postorder[m - 1]; 7 int i = 0; 8 for( ;i < m;i ++) 9 {10 if(root_element == inorder[i])11 break;12 }13 BinaryTreeNode<T>* root = new BinaryTreeNode<T>;14 root->element = root_element;15 root->LeftChild = build_from_post_and_in(postorder, inorder, i);16 root->RightChild = build_from_post_and_in(postorder+i, inorder + i+1, m-i-1);17 return root;18 }
测试函数:
1 int main() 2 { 3 BinaryTreeNode<char> *zero = 0; 4 BinaryTreeNode<char> f('F'), g('G'), h('H'); 5 BinaryTreeNode<char> d('D', &f, &g), e('E', zero, &h); 6 BinaryTreeNode<char> b('B', zero, &d), c('C', zero, &e); 7 BinaryTreeNode<char> a('A', &b, &c); 8 BinaryTree<char> Tree; 9 cout << "广度优先遍历为:" << endl;10 Tree.breadthFirstOrder(&a);11 cout << endl << "先序遍历为:" << endl;12 Tree.preOrder(&a);13 cout << endl << "中序遍历为:" << endl;14 Tree.inOrder(&a);15 cout << endl << "后序遍历为:" << endl;16 Tree.postOrder(&a);17 char *preorder = "ABDFGCEH";18 char *inorder = "BFDGACEH";19 char *postorder = "FGDBHECA";20 int n = strlen(preorder);21 int m = strlen(postorder);22 BinaryTreeNode<char>* root1 = Tree.build_from_pre_and_in(preorder, inorder, n);23 cout << endl << "先序中序构造后广度优先遍历为:" << endl;24 Tree.breadthFirstOrder(root1);25 BinaryTreeNode<char>* root2 = Tree.build_from_post_and_in(postorder, inorder, m);26 cout << endl << "后序中序构造后广度优先遍历为:" << endl;27 Tree.breadthFirstOrder(root2);28 return 0;29 }30 // 测试的二叉树31 // A32 // B C33 // D E34 // F G H
测试结果:
阅读全文
0 0
- [BinaryTree] 二叉树类的实现
- 数据结构 二叉树(binarytree)的实现
- 二叉树类BinaryTree
- BinaryTree(0).关于平衡二叉树的实现
- 二叉树 BinaryTree (实现类+测试用例)
- BinaryTree:学习二叉树的Python库
- 二叉树 BinaryTree.h
- java数据结构与算法之树基本概念及二叉树(BinaryTree)的设计与实现
- 数据结构:树tree和二叉树BinaryTree的实现与代码分析
- java数据结构与算法之树基本概念及二叉树(BinaryTree)的设计与实现
- 二叉树BinaryTree类模板C++实现(功能较全)
- C#实现的BinaryTree
- C#实现的BinaryTree
- org.tinygroup.binarytree-二叉树
- org.tinygroup.binarytree-二叉树
- 线索二叉树(Threaded BinaryTree)
- 线索二叉树(Threaded BinaryTree)
- 数据结构二叉树BinaryTree之性质+推导
- linux每日一学
- 单例模式<静态内部类>
- [Leetcode] 1.Two Sum(unordered_map)
- [STL] map,multimap,unordered_map基本用法
- [Leetcode] 2.Add Two Numbers(List To Long,模拟)
- [BinaryTree] 二叉树类的实现
- [Leetcode] 3.Longest Substring Without Repeating Characters(unordered_map)
- 数据结构实验之图论一:基于邻接矩阵的广度优先搜索遍历
- [Leetcode] 4.Median of Two Sorted Arrays
- linux搭建mysql集群服务负载均衡搭建java连接mysql集群
- 正则表达式 \w \d . \s常用字符的简写
- LeetCode难度和面试频率(转)
- 函数中的静态变量
- [Leetcode] 8.String to Integer (atoi)