如下有一颗树:
树的三种遍历结果分别为:
先序遍历:==》根、左、右
ABCDEFGH
中序遍历:==》左、根、右
CBEDFAGH
后序遍历:==》左、右、根
CEFDBHGA
将代码贴上来以便好查找^O^:
链式存储的二叉树长这样,如下:
二叉树的定义:
typedef char elemtype;
#define END '#'
typedef struct BtNode
{
struct BtNode* leftchild;
struct BtNode* rightchild;
elemtype data;
}BtNode,*pBtNode;
创建一颗树:(利用先序的方法,将空结点用#表示)
BtNode* BuyNode()
{
BtNode* bt=(pBtNode)malloc(sizeof(BtNode));
if(bt==NULL)
exit(1);
return bt;
}
BtNode* Create()
{
BtNode* bt=NULL;
//bt=BuyNode();//ERROR
elemtype elem;
cin>>elem;
if(elem!=END)
{
bt=BuyNode();//OK一定要放在使用之前
bt->data=elem;
bt->leftchild=Create();
bt->rightchild=Create();
}
return bt;
}
三种遍历的递归写法:
void PreTraval(BtNode* ptr)//先序遍历
{
if(ptr!=NULL)
{
cout<<ptr->data<<" ";//根结点
PreTraval(ptr->leftchild);//左子树
PreTraval(ptr->rightchild);//右子树
}
return ;
}
void OrderTraval(BtNode* ptr)//中序遍历
{
if(ptr!=NULL)
{
OrderTraval(ptr->leftchild);//左子树
cout<<ptr->data<<" ";根结点
OrderTraval(ptr->rightchild);右子树
}
return ;
}
void PostTraval(BtNode* ptr)//后序遍历
{
if(ptr!=NULL)
{
PostTraval(ptr->leftchild);//左子树
PostTraval(ptr->rightchild);//右子树
cout<<ptr->data<<" ";根结点
}
return ;
}
三种遍历的非递归写法:
void NicePreTraval(BtNode *ptr)//非递归的先序遍历
{
//方法一:依旧是利用栈来实现,代码有点冗余
//if(ptr==NULL)
// return ;
//stack<pBtNode> st;
//pBtNode pCur=ptr;
//while(1)
//{
// if(pCur==NULL && st.empty())
// break;
// else if(pCur!=NULL)
// {
// cout<<pCur->data<<" ";
// st.push(pCur);
// pCur=pCur->leftchild;
// }
// else if(pCur==NULL)
// {
// pCur=st.top();
// st.pop();
// pCur=pCur->rightchild;
// }
//}
//方法二:利用队列,先让右子树入队,再让左子树入队,完美!!!
stack<BtNode*> st;
if(ptr!=NULL)
st.push(ptr);
while(!st.empty())
{
ptr=st.top();st.pop();//一定要放在这,放在后面就会死循环,因为后边有其他元素入栈。
cout<<ptr->data<<" ";
if(ptr->rightchild!=NULL)
st.push(ptr->rightchild);
if(ptr->leftchild!=NULL)
st.push(ptr->leftchild);
}
}
void NiceOrderTraval(BtNode *ptr)//非递归的中序遍历
{
//方法一:用死循环,代码看起来不是特别整洁
//if(ptr==NULL)
// return ;
//stack<pBtNode> st;
//pBtNode pCur=ptr;
//while(1)
//{
// if(pCur==NULL && st.empty())
// break;
// else if(pCur!=NULL)
// {
// st.push(pCur);
// pCur=pCur->leftchild;
// }
// else if(pCur==NULL)
// {
// pCur=st.top();
// cout<<pCur->data<<" ";
// st.pop();
// pCur=pCur->rightchild;
// }
//}
//方法二:两层while循环,代码比较整洁
stack<BtNode*> st;
while(ptr!=NULL || !st.empty())
{
while(ptr!=NULL)
{
st.push(ptr);
ptr=ptr->leftchild;
}
ptr=st.top();
cout<<ptr->data<<" ";
st.pop();
ptr=ptr->rightchild;
}
}
void NicePostTraval(BtNode *ptr)//非递归的后序遍历
{
//如果给树的节点上添加一个标志域,是不可行的,因为添加的标志位在一次访问之后全部都会被改变,在进行第二次访问时就无法达到预期的效果。
//方法是在中序的非递归上进行改进,采用的是两个指针来进行标志
stack<BtNode*> st;
BtNode *tag=NULL;
while(ptr!=NULL || !st.empty())
{
while(ptr!=NULL)
{
st.push(ptr);
ptr=ptr->leftchild;
}
ptr=st.top();
st.pop();
if(ptr->rightchild==tag || ptr->rightchild==NULL)
{
cout<<ptr->data<<" ";
tag=ptr;
ptr=NULL;//必须得写!!!!!!否则ptr!=NULL,程序将一直无限死循环下去
}
else
{
st.push(ptr);
ptr=ptr->rightchild;
}
}
}
END……