1.前中后序递归遍历
2.前中后序非递归遍历
3.层次遍历
4.求节点个数,求高度
#include"AllHead.h"
#include<stack>
#include<queue>
#include"seqstack.h"
template<class T>
class BinTree;
template<class T>
class BinTreeNode
{
friend class BinTree<T>;
private:
BinTreeNode<T> *left;
BinTreeNode<T> *right;
T data;
public:
BinTreeNode():left(NULL),right(NULL){}
BinTreeNode(T d):data(d),left(NULL),right(NULL){}
T getData(){return data;}
};
template<class T>
class BinTree
{
public:
BinTreeNode<T> *root;
char flag;
public:
BinTree()
{
root = NULL;
flag = '#';
}
BinTree(BinTree<T> &p)
{
BinTree<T> *p = new BinTree<T>;
p->root = p->root;
}
~BinTree()
{
destory();
}
public:
bool IsEmpty()
{
return IsEmpty(root);
}
BinTreeNode<T>* search(T const &x)
{
return search(root,x);
}
void CreatBintree(T *&ch)
{
CreatBintree(root,ch);
}
void CreatBintree()
{
CreatBintree(root);
}
void PreOrder()
{
PreOrder(root);
}
void InOrder()
{
InOrder(root);
}
void PostOrder()
{
PostOrder(root);
}
size_t sizeNode()
{
return sizeNode(root);
}
size_t Height()
{
return Height(root);
}
BinTreeNode<T>* findParent(T x)
{
return findParent(root,x);
}
public://非递归前中后序遍历!!!
void preorder_un()
{
preorder_un(root);
}
void inorder_un()
{
inorder_un(root);
}
void postorder_un()
{
postorder_un(root);
}
void levelorder()//层次遍历
{
levelorder(root);
}
void destory()
{
destory(root);
}
protected:
void destory(BinTreeNode<T> *&p)
{
if(p!=NULL)
{
destory(p->left);
destory(p->right);
delete p;
p=NULL;//这句不能少!!!
}
}
void levelorder(BinTreeNode<T> *&p)
{
queue<T> qe;
T top;
BinTreeNode<T> *t = p;
qe.push(t->data);
BinTreeNode<T> *s;
while(!qe.empty())
{
top = qe.front();
cout<<top<<"-->";
qe.pop();
s = search(p,top);
if(s->left!=NULL)
qe.push(s->left->data);
if(s->right!=NULL)
qe.push(s->right->data);
}
}
//主要思想:任意一个结点N,只要他有左孩子,则在N入栈之后,N的左孩子必然也跟着入栈了
//所以当我们拿到栈顶元素的时候,
//先判断这个元素要么没有左孩子,要么其左孩子已经被访问过。
//所以此时我们就不关心它的左孩子了,我们只关心其右孩子。
//如果右孩子已经被访问过,或是没有右孩子,则输出这个节点
void postorder_un(BinTreeNode<T> *&p)
{
Stack<T> st;
BinTreeNode<T> *t = p;
while(t||!st.isempty())
{
while(t)
{
st.push(t->data);
st.tag[st.lenth()-1] = 0;//设置访问标记。0为第一次访问,1为第二次访问
t = t->left;
}//从根节点开始往左走,一路上每个节点都入栈。
if(st.tag[st.lenth()-1] == 0)//第一次访问时转向同层的有节点
{
st.tag[st.lenth()-1] = 1;
t = search(p,st.gettop());
t = t->right;
}
else
{
while(st.tag[st.lenth()-1] == 1)
{
cout<<st.gettop()<<"--->";
st.pop();
}
}
}
}
void inorder_un(BinTreeNode<T> *&p)
{
T top;
stack<T> st;
BinTreeNode<T> *t = p;
do
{
while(t!=NULL)
{
st.push(t->data);
t = t->left;
}//最左边的节点找到,并一路压入栈中。
if(!st.empty())
{
top = st.top();
st.pop();
cout<<top<<"-->"; //输出左孩子
if(!st.empty())
{
top = st.top();
st.pop();
cout<<top<<"-->";//输出根
}
t = search(p,top);
t = t->right;//转到右孩子上
}
}while(t!=NULL||!st.empty());//依次循环
}
void preorder_un(BinTreeNode<T> *t)
{
if(t!=NULL)
{
T top;
BinTreeNode<T> *p;
stack<T> st;
st.push(t->data);//根节点压入栈中
while(!st.empty())//只要栈不空
{
top = st.top();
st.pop();
cout<<top<<"-->";//取出栈顶元素并输出
p = search(t,top);
if(p->right != NULL)
st.push(p->right->data);//把输出的这个栈顶元素的右孩子压入栈中
if(p->left != NULL)
st.push(p->left->data);//再把左孩子压入栈中 **特别注意这个顺序不能变!!!
}
}
}
/
//十分注意了!!! //
//BinTreeNode<T> *&t(这里的t一定要加引用一定要引用传参,因为传进去的root本身就是指针, //
//如果不是引用传参的话会导致值一直不改变) //
//ch要用引用传参否则会出现错误。(A——+B——+C——+C——+),与上面相同ch本身就是个指向字符串头的地址的指针!!!!//
//其实也就是跟上面的意思是一样的(两者如果不加引用传参的话就跟函数传值调用一样!!!) //
/
void CreatBintree(BinTreeNode<T>*&t,T *&ch)//用字符串创建一个二叉树
{
if(*ch =='\0'||*ch == flag)
t = NULL;
else
{
t = new BinTreeNode<T>(*ch);
//t = new BinTreeNode<T>;
//t->data = *ch;
CreatBintree(t->left,++ch);
CreatBintree(t->right,++ch);
}
}
BinTreeNode<T>* findParent(BinTreeNode<T>*t,T x)
{
if(t == NULL)
return NULL;
BinTreeNode<T> *p = search(t,x);
if(p == NULL||p == t)//这是为了判断p不是根节点!!!
return NULL;
if(t->left->data == x||t->right->data == x)
return t;
p = findParent(t->left,x);
if(p!=NULL)
return p;
return findParent(t->right,x);
}
BinTreeNode<T>* search(BinTreeNode<T> *&t,T const &x)
{
if(t == NULL)
return NULL;
if(t->data == x)
return t;
BinTreeNode<T> *s;
s = search(t->left,x);
if(s!=NULL)
return s;
return search(t->right,x);
}
bool IsEmpty(BinTreeNode<T> *t)
{
return t == NULL;
}
size_t Height(BinTreeNode<T> *t)
{
if(t == NULL)
return 0;
else
return(Height(t->left)>Height(t->right)?(Height(t->left)+1):(Height(t->right)+1));
}
size_t sizeNode(BinTreeNode<T> *t)
{
if(t == NULL)
return 0;
else
return (sizeNode(t->left)+sizeNode(t->right)+1);
}
void PostOrder(BinTreeNode<T>*t)
{
if(t != NULL)
{
PostOrder(t->left);
PostOrder(t->right);
cout<<t->data<<"--+";
}
}
void InOrder(BinTreeNode<T> *t)
{
if(t!=NULL)
{
InOrder(t->left);
cout<<t->data<<"-+-";
InOrder(t->right);
}
}
void PreOrder(BinTreeNode<T> *t)
{
if(t != NULL)
{
cout<<t->data<<"+--";
PreOrder(t->left);
PreOrder(t->right);
}
}
void CreatBintree(BinTreeNode<T> *&t)
{
T input;
cin>>input;
if(input == flag)
{
t = NULL;
}
else
{
//BinTreeNode<T> *newnode = new BinTreeNode<T>;
//newnode->data = t;
t = new BinTreeNode<T>(input);
CreatBintree(t->left);
CreatBintree(t->right);
}
}
};
主函数:
#include"BinTree.h"
int main()
{
BinTree<char> bt;
BinTreeNode<char> *get;
char *input = "ABC##DE##F##G#H##";
int select = 1;
while(select)
{
cout<<"======================List==================="<<endl;
cout<<"[1]creatBinTree [2]PreOrder_BinTree===="<<endl;
cout<<"[3]InOrder_BinTree [4]PostOrder_BinTree==="<<endl;
cout<<"[5]search [6]FindParent=========="<<endl;
cout<<"[7]size [8]height=============="<<endl;
cout<<"[9]CreatBinTreebychar [10]preorder_un ======="<<endl;
cout<<"[11]inorder_un [12]postorder_un ======"<<endl;
cout<<"[13]destory [14]levelorder========="<<endl;
cout<<"============================================="<<endl;
cout<<"请选择:>";
cin>>select;
switch(select)
{
case 1:
bt.CreatBintree();break;
case 2:
cout<<"前序遍历:";
bt.PreOrder();
cout<<endl;
break;
case 3:
cout<<"中序遍历:";
bt.InOrder();
cout<<endl;
break;
case 4:
cout<<"后序遍历:";
bt.PostOrder();
cout<<endl;
break;
case 5:
char ch;
cout<<"请输入您所要找的元素:>";
cin>>ch;
cout<<"所找的值得地址为:<"<<bt.search(ch)<<endl;
break;
case 6:
char ch1;
BinTreeNode<char> *parent;
cout<<"请输入孩子的元素:>";
cin>>ch1;
cout<<"其父节点为:<";
parent = bt.findParent(ch1);
cout<<(*parent).getData()<<endl;
break;
case 7:
size_t size;
size = bt.sizeNode();
cout<<"节点个数为:"<<size<<endl;
break;
case 8:
size_t height;
height = bt.Height();
cout<<"树的高度为:"<<height<<endl;
break;
case 9:
bt.CreatBintree(input);
break;
case 10:
cout<<"非递归前序遍历:";
bt.preorder_un();
cout<<endl;
break;
case 11:
cout<<"非递归中序遍历:";
bt.inorder_un();
cout<<endl;
break;
case 12:
cout<<"非递归后序遍历:";
bt.postorder_un();
cout<<endl;
break;
case 13://注意二叉树摧毁后无法再创建
bt.destory();
cout<<endl;
break;
case 14:
cout<<"层次遍历:";
bt.levelorder();
cout<<endl;
break;
}
}
return 0;
}