前序,中序,后序,层序操作方法不唯一,其中本案例使用链队列实现,当然也可以使用循环链表实现,大家可以自行尝试。
以下是实现创造数,析构,以及实现前序,中序,后序,层序的方法
#ifndef BITREE_H_INCLUDED #define BITREE_H_INCLUDED #include"LinkQueue.h" template<typename T> struct BiNode { T data; BiNode<T>*lchild,*rchild; }; template<typename T> class BiTree { public: BiTree(){root = Creat();} //构造函数,建立一颗树 ~BiTree(){Release(root);} //析构函数 void PreOrder(){PreOrder(root);} //前序 void InOrder(){InOrder(root);}//中序 void PostOrder(){PostOrder(root);} //后序 void LevelOrder(); //层序 private: BiNode<T>*Creat(); void Release(BiNode<T>*bt); void PreOrder(BiNode<T>*bt); void InOrder(BiNode<T>*bt); void PostOrder(BiNode<T>*bt); BiNode<T>*root; }; template<typename T> //前序遍历 void BiTree<T>::PreOrder(BiNode<T>*bt) { if (bt == nullptr) return; else{ cout<<bt->data<<" ";//根 PreOrder(bt->lchild);//左 PreOrder(bt->rchild);//右 } } template<typename T> //中序遍历 void BiTree<T>::InOrder(BiNode<T>*bt) { if (bt == nullptr) return; else{ InOrder(bt->lchild);//左 cout<<bt->data<<" ";//根 InOrder(bt->rchild);//右 } } template<typename T> //后续遍历 void BiTree<T>::PostOrder(BiNode<T>*bt) { if (bt == nullptr) return; else{ PostOrder(bt->lchild);//左 PostOrder(bt->rchild);//右 cout<<bt->data<<" ";//根 } } template<typename T> // 层序遍历 void BiTree<T>::LevelOrder() { LinkQueue<BiNode<T>*>a; if(root == nullptr)return; a.EnQueue(root); while(!a.Empty()) { BiNode<T>*q = a.DeQueue(); std::cout<<q->data<<" "; if(q->lchild!=nullptr){ a.EnQueue(q->lchild); } if(q->rchild!=nullptr){ a.EnQueue(q->rchild); } } } template<typename T> BiNode<T> *BiTree<T>::Creat() { BiNode<T>*bt; char x; cin>>x; if(x =='#') bt = nullptr; else{ bt = new BiNode<T>; bt->data = x; bt->lchild = Creat(); bt->rchild = Creat(); } return bt; } template<typename T> void BiTree<T>::Release(BiNode<T>*bt) { if(bt == nullptr)return; else{ Release(bt->lchild); Release(bt->rchild); delete bt; } } #endif // BITREE_H_INCLUDED
以下是实现层序遍历中运用到的链队列的头文件,里面包括了链表的初始化,入队出队等操作,可以根据需要注释掉多余的,对于本代码无需调试。
#ifndef LINKQUEUE_H_INCLUDED
#define LINKQUEUE_H_INCLUDED
#include<iostream>
#include<string>
using namespace std;
template<typename T>
struct Node
{
T data;
Node<T>*next;
};
template<typename T>
class LinkQueue
{
public:
LinkQueue(); //初始化链表队列
~LinkQueue();
void EnQueue(T x); //入队
T DeQueue(); //出队
T GetHead();
int Empty();
private:
Node<T>*front,*rear;
};
template<typename T>
LinkQueue<T>::LinkQueue() //初始化
{
Node<T>*s = nullptr;
s = new Node<T>;
s->next = nullptr;
front = rear = s;//将头指针和尾指针都指向节点s
}
template<typename T>
LinkQueue<T>::~LinkQueue() //析构函数
{
}
template<typename T>
void LinkQueue<T>::EnQueue(T x)
{
Node<T>*s = nullptr;
s = new Node<T>;
s->data = x; s->next = nullptr;
rear->next = s;
rear = s;
}
template<typename T>
T LinkQueue<T>::DeQueue()
{
T x;
Node<T>*p = nullptr;
if(rear == front) throw"溢出";
p = front->next; x = p->data;
front->next = p->next;
if(p->next == nullptr) rear = front;
delete p;
return x;
}
template<typename T>
T LinkQueue<T>::GetHead()
{
if(rear == front) throw"溢出";
else
return front->next->data;
}
template<typename T>
int LinkQueue<T>::Empty()
{
if(rear == front)
return 1;
else return 0;
}
#endif // LINKQUEUE_H_INCLUDED
引入以上头文件之后,调用main函数就可以直接实现数的一些列遍历操作,注意运行代码输入遍历序列一定要按照满二叉树的顺序,#要保证都可以遍历到。(main.cpp文件)
#include <iostream>
#include"BiTree.h"
using namespace std;
int main()
{
BiTree<char>T{};
cout<<"这个二叉树的前序遍历序列为:";
T.PreOrder();
cout<<endl;
cout<<"这个二叉树的中序遍历序列为:";
T.InOrder();
cout<<endl;
cout<<"这个二叉树的后序遍历序列为:";
T.PostOrder();
cout<<endl;
cout<<"这个二叉树的层序遍历序列为:";
T.LevelOrder();
return 0;
}
具体有其他的遍历方法,希望有兴趣的朋友们可以自行修改,亦可以向作者投稿。
谢谢阅读。(如遇问题欢迎指正,有疑问可提问。)