/* 完成MyTree 非递归的PreOrder,MidOrder,AftOrder,LayerOrder */ #include <iostream.h> #include <assert.h> #define OUT // // 栈 // // template <class T> class Stack; template <class T> class StackNode { T data; StackNode * pNext; friend class Stack<T>; }; template <class T> class Stack { private: StackNode<T> * m_lpTmp; StackNode<T> * m_lpTop; int m_nCount; public: Stack() { m_nCount = 0; m_lpTop = m_lpTmp = NULL; } private: Stack(const Stack<T> &); Stack & operator = (const Stack<T> &); public: // 清空栈 bool ClearStack(); // 栈中元素个数(0 代表空) int GetLength() const; // 入栈 bool Push(const T &); // 出栈 bool Pop(OUT T &); // 获得栈顶元素 bool GetTop(OUT T &); }; // // 栈成员函数 实现 // 清空栈 template <class T> bool Stack<T>::ClearStack() { assert(m_nCount >= 0); if (m_nCount == 0) { return true; } while (m_nCount > 0) { m_lpTmp = m_lpTop->pNext; delete m_lpTop; m_lpTop = m_lpTmp->pNext; } // 如果在栈空间的释放中, 检查到栈结构没有问题, 就返回true if (0 == m_nCount && m_lpTop == NULL) { return true; } // 如果链表结构异常 返货 false m_lpTop = m_lpTmp = NULL; m_nCount = 0; return false; } // 返回栈中元素个数(0 代表空) template <class T> int Stack<T>::GetLength() const { return m_nCount; } // 入栈 template <class T> bool Stack<T>::Push(const T & data) { m_lpTmp = new StackNode<T>; if (m_lpTmp == NULL) { return false; } m_lpTmp->data = data; m_lpTmp->pNext = m_lpTop; m_lpTop = m_lpTmp; m_nCount++; return true; } // 出栈 template <class T> bool Stack<T>::Pop(OUT T & data) { if (m_nCount == 0) { return false; } m_lpTmp = m_lpTop->pNext; data = m_lpTop->data; delete m_lpTop; m_lpTop = m_lpTmp; m_nCount--; return true; } // 获得栈顶元素 template <class T> bool Stack<T>::GetTop(OUT T & data) { if (m_nCount == 0) { return false; } data = m_lpTop->data; return false; } // 队列 / /// template <class T> class Queue; template <class T> class QueNode { T data; QueNode * pNext; friend class Queue<T>; }; template <class T> class Queue { private: QueNode<T> * m_lpFront; //队头 QueNode<T> * m_lpTail; // 队尾 int m_nCount; // 统计队列中结点个数 private: Queue<T> & operator = (Queue<T> &); Queue(Queue<T> &); public: Queue():m_lpFront(NULL), m_lpTail(NULL),m_nCount(0){} ~Queue() { ClearQue(); } public: // 入队 bool EnQue(const T& data); // 出队 bool ExitQue(OUT T& data); // 获取队列长度 int GetLenth() { return m_nCount; } // 获取队头结点, 而不出站 bool GetFront(OUT T& data) { if (m_lpFront != NULL) { data = m_lpFront->data; return true; } return false; } // 清空队列 void ClearQue() { // 将队尾指针当做辅助指针, 一次删除每一个结点 while(m_lpFront) { m_lpTail = m_lpFront->pNext; delete m_lpFront; m_lpFront = m_lpTail; m_nCount--; } assert(m_nCount == 0); assert(m_lpFront == NULL && m_lpTail == NULL); } }; / // 队列成员函数的实现 // 入队 template <typename T> bool Queue<T>::EnQue(const T& data) { assert(m_nCount >= 0); // 如果入队的是第一个结点, 则它既是头结点,也是尾结点 if (m_nCount == 0) { m_lpFront = m_lpTail = new QueNode<T>; // 如果新结点内存分配失败 if (m_lpTail == NULL) { m_lpTail = m_lpFront = NULL; m_nCount = 0; return false; } // 第一个结点成功入队 m_lpTail->pNext = NULL; m_lpTail->data = data; m_nCount++; return true; } // 如果不是第一个入队的结点, 则将其插入队尾 m_lpTail->pNext = new QueNode<T>; if (m_lpTail->pNext == NULL) { return false; } m_lpTail = m_lpTail->pNext; m_lpTail->pNext = NULL; m_lpTail->data = data; m_nCount++; return true; } // 出队 template <typename T> bool Queue<T>::ExitQue(OUT T& data) { assert(m_nCount >= 0); if (m_nCount == 0) { return false; } QueNode<T> * lpTmp = m_lpFront->pNext; data = m_lpFront->data; delete m_lpFront; m_lpFront = lpTmp; m_nCount--; // 当最后一个结点也出队时, 小心! 记住要做如下操作! if (m_nCount == 0) { m_lpTail = NULL; } return true; } /// // 二叉树 /// // 二叉树结点类 template <typename T> struct TreeNode { T data; TreeNode * lpLChild; TreeNode * lpRChild; int m_nHeight; }; // 二叉树类 template <typename T> class BinaryTree { private: TreeNode<T> *m_lpRoot; int m_nHeight; private: BinaryTree(const BinaryTree<T> &); BinaryTree & operator = (BinaryTree &); public: BinaryTree():m_lpRoot(NULL), m_nHeight(0){} public: // 增加一个结点(做lpInsertNode 的子树) TreeNode<T> * AddNode(const T& data, TreeNode<T> * lpInsertNode); // 删除一个子树 (默认参表示清空树) bool DelSubTree(const TreeNode<T> * lpNode = m_lpRoot); // ... typedef void (BinaryTree<T>::*funPtr)( TreeNode<T>* lpCurNode ); // 显示树 void PrintNode( TreeNode<T>* lpCurNode ) { cout << "结点数据为: " << lpCurNode->data << '/t' << "所在层为:" << lpCurNode->m_nHeight << endl; } // // 非递归的实现树的四种遍历: PreOrder,MidOrder,AftOrder,LayerOrder // // // 先序遍历 void PreOrder(TreeNode<T> * lpCurNode , funPtr = PrintNode); // 中序遍历 void MidOrder(TreeNode<T> * lpCurNode , funPtr = PrintNode); // 后续遍历 void AftOrder(TreeNode<T> * lpCurNode , funPtr = PrintNode); // 层序遍历 void LayerOrder(TreeNode<T> * lpCurNode , funPtr = PrintNode); }; // 二叉树 成员函数实现 // 增加一个结点(做lpInsertNode 的子树) // 如果插入成功, 返回新结点的指针, 如果失败, 则返回NULL template <typename T> TreeNode<T> * BinaryTree<T>::AddNode(const T& data, TreeNode<T> * lpInsertNode) { TreeNode<T> * lpTmpNode = NULL; // 如果 是向空树中插入新结点 if (m_lpRoot == NULL) { // 如果插入为之合法(即选择在根结点插入数据) if (lpInsertNode == NULL) { lpTmpNode = new TreeNode<T>; lpTmpNode->data = data; lpTmpNode->lpLChild = NULL; lpTmpNode->lpRChild = NULL; lpTmpNode->m_nHeight = 1; m_lpRoot = lpTmpNode; m_nHeight = 1; // 返回新插入结点的指针 return m_lpRoot; } // 如果选择的插入位置非法, 返回NULL else return NULL; } // 以下判定 树非空的情况下 插入新结点 是否合法. // 如果选择的插入位置合法, 则插入值, 否则返回为NULL, 不执行任何操作. // 如果 选择的结点为空 else if (lpInsertNode == NULL) { return NULL; } // 优先检索 lpInsertNode左子树, 然后检索右子树, 找到可以插入新结点的位置. // 如果左右子树都满了, 则返回假值 else if (lpInsertNode->lpLChild == NULL) { lpTmpNode = new TreeNode<T>; lpTmpNode->data = data; lpTmpNode->lpLChild = NULL; lpTmpNode->lpRChild = NULL; lpTmpNode->m_nHeight = lpInsertNode->m_nHeight+1; lpInsertNode->lpLChild = lpTmpNode; } else if (lpInsertNode->lpRChild == NULL) { lpTmpNode = new TreeNode<T>; lpTmpNode->data = data; lpTmpNode->lpLChild = NULL; lpTmpNode->lpRChild = NULL; lpTmpNode->m_nHeight = lpInsertNode->m_nHeight+1; lpInsertNode->lpRChild = lpTmpNode; } // 插入位置非法的一种情况( 选择的结点 左右孩子 都非空, 无法完成插入操作) else { // 插入失败, 返回NULL return NULL; } // 更新数的层数 if (lpTmpNode->m_nHeight > this->m_nHeight) { this->m_nHeight = lpTmpNode->m_nHeight; } // 返回 新插入结点的指针 return lpTmpNode; } // 删除一个子树 (默认参表示清空树) template <typename T> bool BinaryTree<T>::DelSubTree(const TreeNode<T> * lpNode) { return false; } // 先序遍历 template <typename T> void BinaryTree<T>::PreOrder(TreeNode<T> * lpCurNode, funPtr fun) { if (fun == NULL) { return ; } Stack<TreeNode<T> * > s; if (lpCurNode == NULL) { return ; } do { // 访问根结点 (this->*fun)(lpCurNode); // 右子树入栈 if (lpCurNode->lpRChild != NULL) { s.Push(lpCurNode->lpRChild); } //左子树入栈 if (lpCurNode->lpLChild != NULL) { s.Push(lpCurNode->lpLChild); } } while (s.Pop(lpCurNode)); } // 中序遍历 template <typename T> void BinaryTree<T>::MidOrder(TreeNode<T> * lpCurNode, funPtr fun) { if (fun == NULL) { return ; } Stack< TreeNode<T> * > stack; while (true) { // 一直走到最左下角的叶子节点 while (lpCurNode != NULL) { stack.Push(lpCurNode); lpCurNode = lpCurNode->lpLChild; } // 出栈, 解决问题 if (stack.Pop(lpCurNode) == false) { //如果栈为空, 则问题得到完全解决. return; } (this->*fun)(lpCurNode); lpCurNode = lpCurNode->lpRChild; } } // 后续遍历 template <typename T> void BinaryTree<T>::AftOrder(TreeNode<T> * lpCurNode, funPtr fun) { if (fun == NULL) { return ; } Stack< TreeNode<T> * > stack; TreeNode<T> * lpFlagNode = NULL; while (true) { while (lpCurNode != NULL) { stack.Push(lpCurNode); lpCurNode = lpCurNode->lpLChild; } // 出栈, 解决问题 if (stack.Pop(lpCurNode) == false) { //如果栈为空, 则问题得到完全解决. return; } if (lpCurNode->lpRChild == lpFlagNode || lpCurNode->lpRChild == NULL) { (this->*fun)(lpCurNode); lpFlagNode = lpCurNode; lpCurNode = NULL; } else { stack.Push(lpCurNode); lpCurNode = lpCurNode->lpRChild; } } } // 层序遍历 template <typename T> void BinaryTree<T>::LayerOrder(TreeNode<T> * lpCurNode, funPtr fun) { if (fun == NULL) { return ; } Queue < TreeNode<T> * > que; que.EnQue(lpCurNode); while( que.ExitQue(lpCurNode) ) { (this->*fun)(lpCurNode); if (lpCurNode->lpLChild != NULL) { que.EnQue(lpCurNode->lpLChild); } if (lpCurNode->lpRChild != NULL) { que.EnQue(lpCurNode->lpRChild); } } } // // 测试 // void main() { BinaryTree<int> bt; // 向树种插入数据 // 1 // 2 5 // 3 4 6 TreeNode<int> * Tmp1 = NULL, *Tmp2 = NULL; Tmp1 = bt.AddNode(1, NULL); Tmp2 = bt.AddNode(2, Tmp1); bt.AddNode(3, Tmp2); bt.AddNode(4, Tmp2); Tmp2 = bt.AddNode(5, Tmp1); bt.AddNode(6, Tmp2); cout << ">>>>>>>>>>>>>>>>>>>>>>>>>>>>" << endl; cout << "先序遍历:" << endl; bt.PreOrder(Tmp1); cout << ">>>>>>>>>>>>>>>>>>>>>>>>>>>>" << endl; cout << "中序遍历:" << endl; bt.MidOrder(Tmp1); cout << ">>>>>>>>>>>>>>>>>>>>>>>>>>>>" << endl; cout << "后序遍历:" << endl; bt.AftOrder(Tmp1); cout << ">>>>>>>>>>>>>>>>>>>>>>>>>>>>" << endl; cout << "层序遍历:" << endl; bt.LayerOrder(Tmp1); }