二叉樹C++實現
阿新 • • 發佈:2019-02-18
最近整理原來的一些程式碼,腦子有點不好使,還是記下來吧。
//binary_tree.h,遍歷包含了遞迴和非遞迴兩種,層次遍歷
#ifndef _BINARY_TREE_H_ #define _BINARY_TREE_H_ template<class T> struct BiNode { T data; BiNode<T>* lchild, *rchild; }; template<class T> class BiTree { public: BiTree(); ~BiTree(); BiNode<T>* GetRoot(); void PreOrder(BiNode<T>* node); void InOrder(BiNode<T>* node); void PostOrder(BiNode<T>* node); //非遞迴實現 void PreOrderNonRec(BiNode<T>* node); void InOrderNonRec(BiNode<T>* node); void PostOrderNonRec(BiNode<T>* node); void LevelOrder(BiNode<T>* node);//層次遍歷 protected: private: BiNode<T>* m_root; BiNode<T>* Create(); void Release(BiNode<T>* root); }; #endif
//bianry_tree.cpp
【測試】#include <iostream> #include <stack> #include <queue> using namespace std; template<class T> BiNode<T>* BiTree<T>::GetRoot() { return m_root; } template<class T> BiTree<T>::BiTree() { m_root = new BiNode<T>; m_root = Create(); } template<class T> BiTree<T>::~BiTree() { Release(m_root); } template<class T> BiNode<T>* BiTree<T>::Create() { char ch; cin>>ch; BiNode<T>* pnode; if (ch == '#') pnode = NULL; else { pnode = new BiNode<T>; pnode->data = ch; pnode->lchild = Create(); pnode->rchild = Create(); } return pnode; } template<class T> void BiTree<T>::Release( BiNode<T>* root ) { if(root != NULL) { Release(root->lchild); Release(root->rchild); } } template<class T> void BiTree<T>::PreOrder(BiNode<T>* node) { //TLR的第一個一定是樹根 if(node == NULL) return; else { cout<<node->data<<" "; PreOrder(node->lchild); PreOrder(node->rchild); } } template<class T> void BiTree<T>::InOrder(BiNode<T>* node) { //由前序遍歷和中序遍歷可以確定唯一二叉樹 //後序遍歷和中序遍歷也可以 //但是前序和後序一起不可以 //特點是 前後定根,中序定左右 if(node == NULL) return; else { InOrder(node->lchild); cout<<node->data<<" "; InOrder(node->rchild); } } template<class T> void BiTree<T>::PostOrder(BiNode<T>* node) { //LRT的最後一個一定是樹根 if(node == NULL) return; else { PostOrder(node->lchild); PostOrder(node->rchild); cout<<node->data<<" "; } } template<class T> void BiTree<T>::PreOrderNonRec(BiNode<T>* node) { stack<BiNode<T>*> s; BiNode<T>* p = node; while(p != NULL || !s.empty()) { while(p != NULL) { cout<<p->data<<" "; s.push(p); p = p->lchild; } if (!s.empty()) { p = s.top(); s.pop(); p = p->rchild; } } } template<class T> void BiTree<T>::InOrderNonRec(BiNode<T>* node) { //先序遍歷非遞迴需要藉助stack s來實現,模擬遞迴呼叫 //總的迴圈邊界是當前節點不為空或者stack不空, //@1 在當前節點p非空時候,將p入棧s,p的左子樹賦給p,保證左子樹都能入棧 // p為空時候,也就是左子樹最左邊訪問到了,這時候在棧非空的時候 //@2 取棧頂給p,輸入p,出棧,這時候最底層的最左邊節點訪問了,將p的右子樹賦給p,重複@1 stack<BiNode<T>*> s; BiNode<T>* p = node; while(p != NULL || !s.empty()) { while (p != NULL) { s.push(p); p = p->lchild; } if (!s.empty()) { p = s.top(); cout<<p->data<<" "; s.pop(); p = p->rchild; } } } template<class T> void BiTree<T>::PostOrderNonRec(BiNode<T>* node) { //要保證根結點在左孩子和右孩子訪問之後才能訪問, //因此對於任一結點P,先將其入棧。如果P不存在左孩子和右孩子,則可以直接訪問它; //或者P存在左孩子或者右孩子,但是其左孩子和右孩子都已被訪問過了,則同樣可以直接訪問該結點。 //若非上述兩種情況,則將P的右孩子和左孩子依次入棧,這樣就保證了每次取棧頂元素的時候, //左孩子在右孩子前面被訪問,左孩子和右孩子都在根結點前面被訪問。 if(node == NULL) return; stack<BiNode<T>*> s; s.push(node);//node是root BiNode<T>* pre = NULL; BiNode<T>* cur; while(!s.empty()) { cur = s.top(); if(cur->lchild == NULL && cur->rchild == NULL || (pre != NULL)&&(pre == cur->lchild || pre == cur->rchild) )//上一次訪問的是當前節點的左子樹 { cout<<cur->data<<" "; s.pop(); pre = cur; } else { if(cur->rchild) s.push(cur->rchild); if (cur->lchild) s.push(cur->lchild); } } } template<class T> void BiTree<T>::LevelOrder(BiNode<T>* node) { //層次遍歷需要queue來實現,思路: //@1初始化queue // if root為空 返回 //@2 push(root) //@3 while(queue不為空) // s <-- queue.front() // queue.pop() // 輸入s.data // if(s的左子樹不空) // s的左子樹入隊 // if(s的右子樹不空) // s的右子樹入隊 queue<BiNode<T>*> q; BiNode<T>* s = node; if(s == NULL) return; q.push(s); while(!q.empty()) { s= q.front(); q.pop(); cout<<s->data<<" "; if (s->lchild) q.push(s->lchild); if(s->rchild) q.push(s->rchild); } }
#include "list.h" #include "binary_tree.h" #include <iostream> using namespace std; int main() { BiTree<char> my_tree; my_tree.PreOrder(my_tree.GetRoot()); cout<<endl; my_tree.PreOrderNonRec(my_tree.GetRoot()); cout<<endl; my_tree.InOrder(my_tree.GetRoot()); cout<<endl; my_tree.InOrderNonRec(my_tree.GetRoot()); cout<<endl; my_tree.PostOrder(my_tree.GetRoot()); cout<<endl; my_tree.LevelOrder(my_tree.GetRoot()); cout<<endl; my_tree.PostOrderNonRec(my_tree.GetRoot()); cout<<endl; }