二叉查找树_前序遍历_中序_后序_递归与非递归写法_层次遍历_以及树形显示
2016-10-29 21:31
417 查看
#include <iostream> #include <stack> using namespace std; template<typename T> struct BinaryNode { T element; BinaryNode<T> *left; BinaryNode<T> *right; BinaryNode(const T &theElement, BinaryNode *lt, BinaryNode *rt) : element(theElement), left(lt), right(rt) {} }; template<typename T> class BinarySearchTree { public: BinarySearchTree() { root = nullptr; } BinarySearchTree(const BinarySearchTree& rhs) { //复制构造函数 root = clone(rhs.root); } ~BinarySearchTree(); const T &findMin() const { return findMin(root)->element; } const T &findMax() const { return findMax(root)->element; } bool contains(const T& x) const; T& getNode(const T& e) { //得到元素为e的结点 return getNode(e, root)->element; } bool isEmpty() const { if (root == nullptr) return true; return false; } void PreprintTree() const { PreprintTree(root); } void InprintTree() const { InprintTree(root); } void PostprintTree() const { PostprintTree(root); } void LevelprintTree() const { LevelprintTree(root); } void PreprintTree_N() const { PreprintTree_N(root); } void InprintTree_N() const { InprintTree_N(root); } void PostprintTree_N() const { PostprintTree_N(root); } void DisplayTreeShape(int level = 1) const { DisplayTreeShape(root, level); } void makeEmpty(); void insert(const T &x); void remove(const T &x); int Depth(); int CountLeaf() { BinaryNode<T> *p = root; int count = 0; CountLeaf(p, count); return count; } const BinarySearchTree& operator = (const BinarySearchTree& rhs); private: BinaryNode<T> *root; //指向树根结点的指针 void insert(const T & x, BinaryNode<T> * & t); void remove(const T & x, BinaryNode<T> * & t); BinaryNode<T> * findMin(BinaryNode<T> *t) const; BinaryNode<T> * findMax(BinaryNode<T> *t ) const; bool contains(const T & x, BinaryNode<T> *t) const; BinaryNode<T> * getNode(const T &x, BinaryNode<T> *t); void makeEmpty( BinaryNode<T> * & t ); //利用 递归 算法 计算树的 深度 int Depth( BinaryNode<T> * t, int level, int &depth); //利用 递归 算法 计算树的 高度 void CountLeaf(BinaryNode<T> * t, int &count); void PreprintTree( BinaryNode<T> * t ) const; //先序遍历 void InprintTree( BinaryNode<T> *t ) const; //中序遍历 void PostprintTree( BinaryNode<T> * t ) const; //后序遍历 void LevelprintTree( BinaryNode<T> * t) const; //层次遍历 void PreprintTree_N( BinaryNode<T> * t) const; //非递归先序遍历 void InprintTree_N( BinaryNode<T> * t) const; //非递归中序遍历二叉树 void PostprintTree_N( BinaryNode<T> * t) const; //非递归后序遍历二叉树 void DisplayTreeShape(BinaryNode<T> *bt, int level) const; //二叉树的树形显示算法 BinaryNode<T> * clone( BinaryNode<T> * t ) const; }; template<typename T> bool BinarySearchTree<T>::contains(const T& x) const { return contains(x, root); } template<typename T> bool BinarySearchTree<T>::contains(const T & x, BinaryNode<T> *t) const { if (t == nullptr) return false; else if (x < t->element) // x 小, 说明应该在左边找 return contains(x, t->left); else if (t->element < x) // x 大, 说明应该在右面找 return contains(x, t->right); else return true; } template<typename T> BinaryNode<T>* BinarySearchTree<T>::getNode(const T & x, BinaryNode<T> *t) { if (t == nullptr) return nullptr; else if (x < t->element) return getNode(x, t->left); else if (t->element < x) return getNode(x, t->right); return t; } //findMin--返回指向树中包含最小元的结点的指针 template<typename T> BinaryNode<T> * BinarySearchTree<T>::findMin(BinaryNode<T> *t) const { if (t == nullptr) return nullptr; if (t->left == nullptr) return t; return findMin(t->left); } template<typename T> BinaryNode<T>* BinarySearchTree<T>::findMax(BinaryNode<T> *t) const { if (t != nullptr) while (t->right != nullptr) { t = t->right; } return t; } template<typename T> void BinarySearchTree<T>::insert(const T &x) { insert(x, root); } /************************************************************************/ /* x is the item to insert */ /* t is the node that roots the subtree*/ /* Set the new root of the subtree*/ ///* 只有当一个新树叶生成时候,t才改变. ///* t 是到p->left或p->right的引用.==> 意味着p->left或p->right将会改变为指向新结点. /************************************************************************/ template<typename T> void BinarySearchTree<T>::insert(const T & x, BinaryNode<T> * & t) { if (t == nullptr) //没有结点,在该位置处添加新结点 t = new BinaryNode<T>(x, nullptr, nullptr); else if (x < t->element) //x 小, 在左子树查询 insert(x, t->left); else if (t->element < x) //x 大, 在右子树查询 insert(x, t->right); else; //Duplicate, do nothing; } template<typename T> void BinarySearchTree<T>::remove(const T &x) { remove(x, root); } /************************************************************************/ /* x is item to remove */ /* t is the node that roots the subtree */ /* Set the new root of the subtree */ /* 1.结点是一片树叶时 -- 可被立即删除*/ /* 2.结点有一个儿子, 则该结点可以在其父节点调整他的链 以绕过该结点后被删除 */ /* 3.结点有两个儿子, 则其右子树的最小数据代替该结点的数据,并递归删除那个结点 */ /* 注: 右子树中的最小的结点不可能有左结点 */ /************************************************************************/ template<typename T> void BinarySearchTree<T>::remove(const T &x, BinaryNode<T> * & t) { if (t == nullptr) return; //Item not found; do nothing if (x < t->element) //x 小,在左子树递归查找 remove(x, t->left); else if (t->element < x) //x 大,在右子树递归查找 remove(x, t->right); else if (t->left != nullptr && t->right != nullptr) //two children { //在右子树中查找最小数据代替该结点数据.; t->element = findMin(t->right)->element; remove(t->element, t->right); //删除该结点 } else //只有一个结点或是树叶. 调整它的链,以绕过该结点后被删除. { BinaryNode<T> *oldNode = t; t = (t->left != nullptr) ? t->left : t->right; delete oldNode; } } /************************************************************************/ ///* Destructor for the tree /************************************************************************/ template<typename T> BinarySearchTree<T>::~BinarySearchTree() { makeEmpty(); } template<typename T> void BinarySearchTree<T>::makeEmpty() //公有函数 { makeEmpty(root); } /************************************************************************/ ///* Internal method to make subtree empty -- 私有函数 /************************************************************************/ template<typename T> void BinarySearchTree<T>::makeEmpty(BinaryNode<T> * & t) { if (t != nullptr) { makeEmpty(t->left); makeEmpty(t->right); delete t; } t = nullptr; } /************************************************************************/ ///* Deep copy /************************************************************************/ template<typename T> const BinarySearchTree<T>& BinarySearchTree<T>::operator = (const BinarySearchTree &rhs) { if (this != &rhs) { makeEmpty(); root = clone(rhs.root); } return *this; } /************************************************************************/ ///* Internal method to clone subtree. -- 递归复制结点 /************************************************************************/ template<typename T> BinaryNode<T>* BinarySearchTree<T>::clone(BinaryNode<T> * t) const { if (t == nullptr) return nullptr; return new BinaryNode<T>( t->element, clone(t->left), clone(t->right) ); } //利用递归计算树的深度 template<typename T> int BinarySearchTree<T>::Depth() { BinaryNode<T> *t = root; int depth = 0; if (root == nullptr) return 0; Depth(t, 1, depth); return depth; } //由public的函数Depth调用, 完成树的深度的计算,p是根结点,Level是层,depth用来返回树的深度 template<typename T> int BinarySearchTree<T>::Depth(BinaryNode<T> *t, int level, int &depth) { if (level > depth) depth = level; //层数 if (t->left) Depth(t->left, level + 1, depth); //递归遍历左子树,且层数加1 if (t->right) Depth(t->right, level + 1, depth); //递归遍历右子树, 且层数加1 return 0; } template<typename T> //利用 递归 算法 计算树的 高度 void BinarySearchTree<T>::CountLeaf(BinaryNode<T> * t, int &count) { if (t == nullptr) return; //为空时,退出 // CountLeaf(t->left, count); // CountLeaf(t->right, count); if (!(t->left) && !(t->right)) { //儿子为空时 count++; } CountLeaf(t->left, count); CountLeaf(t->right, count); } /************************************************************************/ ///* printTree --- 前序遍历 /************************************************************************/ template<typename T> void BinarySearchTree<T>::PreprintTree(BinaryNode<T> * t) const { if (t != nullptr) { cout << t->element << ' '; PreprintTree(t->left); PreprintTree(t->right); } } //中序遍历 template<typename T> void BinarySearchTree<T>::InprintTree(BinaryNode<T> * t ) const { if (t != nullptr) { InprintTree(t->left); cout << t->element << ' '; InprintTree(t->right); } } //后序遍历 template<typename T> void BinarySearchTree<T>::PostprintTree(BinaryNode<T> * t) const { if (t != nullptr) { PostprintTree(t->left); PostprintTree(t->right); cout << t->element << ' '; } } //利用队列Queue层次遍历二叉树 template<typename T> void BinarySearchTree<T>::LevelprintTree( BinaryNode<T> * t) const { const int maxn = 1024; BinaryNode<T> *Queue[maxn]; //一维数组作为队列 BinaryNode<T> *tmp; int front = 0, rear = 0; //队列初始为空 if (root) { Queue[rear++] = root; //二叉树的根结点指针入队列 while (front != rear) { tmp = Queue[front++]; //队首的元素出队列 if (tmp) cout << tmp->element << ' '; //输出结点值 if (tmp->left) Queue[rear++] = tmp->left; if (tmp->right) Queue[rear++] = tmp->right; } } } //先序遍历 template<typename T> void BinarySearchTree<T>::PreprintTree_N( BinaryNode<T> * t) const //非递归先序遍历 { const int maxn = 1024; BinaryNode<T> *Stack[maxn]; int top = 0; BinaryNode<T> *tmp = root; //将根结点的指针赋值给tmp // cout << "Debug :\n"; while (tmp || top != 0) { // cout << "debug : \n"; while (tmp) { cout << tmp->element << ' '; Stack[top++] = tmp; //右孩子入栈 tmp = tmp->left; //一直递归到最左的结点 } if (top) { //栈不为空, 从栈中取出一个结点指针 tmp = Stack[--top]; tmp = tmp->right; } } } //中序非递归遍历二叉树 (LDR) template<typename T> void BinarySearchTree<T>::InprintTree_N( BinaryNode<T> * t) const //非递归中序遍历二叉树 { const int maxn = 1024; BinaryNode<T> *Stack[maxn]; int top = 0; BinaryNode<T> *tmp = root; while (tmp || top != 0) { while (tmp) { //迭代到最左的子树 Stack[top++] = tmp; //左子树入栈 tmp = tmp->left; } if (top) { tmp = Stack[--top]; //出栈最左的子树 cout << tmp->element << ' '; //输出该元素 tmp = tmp->right; //并指向右结点开始迭代 } } } //非递归后序遍历二叉树 (LRD) template<typename T> void BinarySearchTree<T>::PostprintTree_N( BinaryNode<T> * t) const { const int maxn = 1024; struct Mystack { BinaryNode<T> * link; int flag; }; Mystack Stack[maxn]; BinaryNode<T> * p = root, *tmp; if (root == nullptr) return; int top = -1, //栈顶初始化 sign = 0; //为结点tmp 的标志量 while ( p != nullptr || top != -1) { while (p != nullptr) //遍历到最左 { Stack[++top].link = p; //并且一直入栈 Stack[top].flag = 1; //设置flag为第一次入栈 p = p->left; } if (top != -1) { tmp = Stack[top].link; sign = Stack[top].flag; top--; //出栈 if (sign == 1) //结点第一次进栈 { top++; Stack[top].link = tmp; Stack[top].flag = 2; //标记为第二次出栈 p = tmp->right; } else { //第二次出栈就输出 cout << tmp->element << ' '; //访问该结点数据域 p = nullptr; } } } } //树形显示二叉树,也是中序遍历 template<typename T> void BinarySearchTree<T>::DisplayTreeShape(BinaryNode<T> *bt, int level) const { if (bt) //二叉树的树形显示算法 { cout << endl; for (int i = 0; i < level - 1; i++) cout << " "; //确保在第level列显示结点 cout << bt->element; //显示结点 DisplayTreeShape(bt->left, level - 1); //空二叉树不显示 // cout << endl; //显示右子树 DisplayTreeShape(bt->right, level + 2); //显示左子树 } } int main() { // srand((unsigned)time(nullptr)); int testData, t = 0; BinarySearchTree<int> test; cout << "输入数字个数: \n"; cin >> t; cout << "输入数字: \n"; while (t--) { testData = rand() % 500 + 1; test.insert(testData); } cout << "\n全部元素为: \n"; test.PreprintTree(); cout << endl; // cin >> testData; //不符合查找二叉树 // test.getNode(testData) = 10000; cout << "\nMax = " << test.findMax() << endl; cout << "Min = " << test.findMin() << endl; cout << "输入查找元素: \n"; cin >> testData; cout << "是否包含 " << testData << " : " << test.contains(testData) << endl; test.PreprintTree(); cout << endl; cout << "输入删除元素: \n"; cin >> testData; test.remove(testData); cout << "\n树的高度: " << test.Depth() << endl; cout << "\n叶子的个数: " << test.CountLeaf() << endl; cout << endl; cout << "先序遍历树元素: \n"; test.PreprintTree(); cout << "\n\n中序遍历树元素: \n"; test.InprintTree(); cout << "\n\n后序遍历树元素: \n"; test.PostprintTree(); cout << "\n\n层次遍历树元素: \n"; test.LevelprintTree(); cout << "\n\n先序遍历树元素(非递归): \n"; test.PreprintTree_N(); cout << "\n\n中序遍历树元素(非递归): \n"; test.InprintTree_N(); cout << "\n\n后序遍历树元素(非递归): \n"; test.PostprintTree_N(); cout << "\n\n二叉树的树形显示算法: \n"; test.DisplayTreeShape(43); cout << endl; return 0; }
相关文章推荐
- 二叉树创建、前序遍历、中序遍历、后序遍历 的 递归与非递归实现 以及 层次遍历
- 二叉树的先序、中序以及后序遍历(递归与非递归方法)
- python实现二叉树的建立以及遍历(递归前序、中序、后序遍历,队栈前序、中序、后序、层次遍历)
- 树的遍历实现,前序遍历,中序遍历,后序遍历以及层次遍历的迭代与递归实现
- 二叉树的前序、中序、后序、层次遍历的递归与非递归实现
- 数据结构(一)——二叉树 前序、中序、后序、层次遍历及非递归实现 查找、统计个数、比较、求深度的递归实现
- 二叉树 前序、中序、后序、层次遍历及非递归实现 查找、统计个数、比较、求深度的递归实现
- 二叉树的先序,中序,后序,层次,递归,非递归遍历
- 二叉树前序、中序、后序遍历非递归写法的透彻解析
- 二叉树的先序、中序、后序遍历方法(递归与非递归方法)——《数据结构》
- 二叉树的先序,中序,层次遍历,递归与非递归实现
- 二叉树 前序、中序、后序、层次遍历及非递归实现 查找、统计个数、比较、求深度的递归实现
- 二叉树的先序,中序,后序,层次的递归及非递归遍历
- 数据结构 —— 二叉树 前序、中序、后序、层次遍历及非递归实现 查找、统计个数、比较、求深度的递归实现
- 二叉树 的先序 中序、后序遍历、层次遍历以及树状打印等操作
- 数据结构(六)——二叉树 前序、中序、后序、层次遍历及非递归实现 查找、统计个数、比较、求深度的递归实现
- 二叉树前序、中序、后序遍历非递归写法的透彻解析
- 数据结构(六)——二叉树 前序、中序、后序、层次遍历及非递归实现 查找、统计个数、比较、求深度的递归实现
- 二叉树相关操作(前序遍历,中序遍历,后序遍历,层次序遍历等)递归和非递归实现
- 二叉树前序、中序、后序遍历非递归写法的透彻解析