二叉树一些非递归算法总结
#include <bits/stdc++.h>
using namespace std;
#define MAXSIZE 10000
typedef char TElemType;
typedef struct BiTNode
{
TElemType data;
struct BiTNode *lchild,*rchild;
}BiTNode,*BiTree;
BiTree CreateNode(char* data) //创建一个节点
{
BiTree temp = (BiTree)malloc(sizeof(BiTNode));
temp->data = *data;
temp->lchild = NULL;
temp->rchild = NULL;
return temp;
}
BiTree CreateBiTreeNonRecur(char* str)
{
BiTree stack[MAXSIZE];
int top = 0;
if(*str == '\0')
{
cout<<"创建一个空的二叉树";
return NULL;
}
BiTree root = NULL;
BiTree tempRoot = NULL; //当前指向节点
BiTree temp =NULL;
root = CreateNode(str);
tempRoot = root;
while(*str != '\0')
{ str++;
if(*(str-1)!= '#') //建树过程中如果一直未碰到@符号,则持续建立左子树
{ //并将节点压入栈中
stack[top++] = tempRoot;
if(*str != '#') //判断当前节点是不是@节点,如果是的左子树为空
{
temp = CreateNode(str);
tempRoot->lchild = temp;
tempRoot = temp;
}
else
{
tempRoot->lchild =NULL;
}
}
if(*(str-1) =='#' && top >0) //若前一个节点是@,则出栈,建立右子树
{
tempRoot = stack[--top];
if(*str != '#')//判断当前节点是不是@节点,如果是的右子树为空
{
temp = CreateNode(str);
tempRoot->rchild = temp;
tempRoot = temp;
}
else
tempRoot->rchild =NULL;
}
}
return root;
}
void pre_traverse(BiTree pTree)
{
stack<BiTree> s; //创建一个空栈
BiTree node_pop; //用来保存出栈节点
BiTree pCur = pTree; //定义用来指向当前访问的节点的指针
//直到当前节点pCur为NULL且栈空时,循环结束
while(pCur || !s.empty())
{
//从根节点开始,输出当前节点,并将其入栈,
//同时置其左孩子为当前节点,直至其没有左孩子,及当前节点为NULL
printf("%c ", pCur->data);
s.push(pCur);
pCur = pCur->lchild;
//如果当前节点pCur为NULL且栈不空,则将栈顶节点出栈,
//同时置其右孩子为当前节点,循环判断,直至pCur不为空
while(!pCur && !s.empty())
{
pCur = s.top();
node_pop=s.top();
s.pop();
pCur = pCur->rchild;
}
}
}
void in_traverse(BiTree pTree)
{
stack<BiTree> s; //创建一个空栈
BiTree node_pop; //用来保存出栈节点
BiTree pCur = pTree; //定义指向当前访问的节点的指针
//直到当前节点pCur为NULL且栈空时,循环结束
while(pCur || !s.empty())
{
if(pCur->lchild)
{
//如果pCur的左孩子不为空,则将其入栈,并置其左孩子为当前节点
s.push(pCur);
pCur = pCur->lchild;
}
else
{
//如果pCur的左孩子为空,则输出pCur节点,并将其右孩子设为当前节点,看其是否为空
printf("%c ", pCur->data);
pCur = pCur->rchild;
//如果为空,且栈不空,则将栈顶节点出栈,并输出该节点,
//同时将它的右孩子设为当前节点,继续判断,直到当前节点不为空
while(!pCur && !s.empty())
{
pCur = s.top();
printf("%c ",pCur->data);
node_pop=s.top();
s.pop();
pCur = pCur->rchild;
}
}
}
}
void beh_traverse(BiTree pTree)
{
stack<BiTree> s; //创建一个空栈
BiTree node_pop; //用来保存出栈的节点
BiTree pCur; //定义指针,指向当前节点
BiTree pPre = NULL; //定义指针,指向上一各访问的节点
//先将树的根节点入栈
s.push(pTree);
//直到栈空时,结束循环
while(!s.empty())
{
pCur = s.top(); //当前节点置为栈顶节点
if((pCur->lchild==NULL && pCur->rchild==NULL) ||
(pPre!=NULL && (pCur->lchild==pPre || pCur->rchild==pPre)))
{
//如果当前节点没有左右孩子,或者有左孩子或有孩子,但已经被访问输出,
//则直接输出该节点,将其出栈,将其设为上一个访问的节点
printf("%c ", pCur->data);
node_pop=s.top();
s.pop();
pPre = pCur;
}
else
{
//如果不满足上面两种情况,则将其右孩子左孩子依次入栈
if(pCur->rchild != NULL)
s.push(pCur->rchild);
if(pCur->lchild != NULL)
s.push(pCur->lchild);
}
}
}
int levelOrderTraverse(BiTree& T)
{
queue<BiTree> q;
BiTree p = NULL;int count1=0;
if(T)//若根结点非空,则入队列
{
q.push(T);
}
while(!q.empty())//队列非空
{
p = q.front();
q.pop();
cout<<p->data<<" ";
if(p->lchild)//左孩子不空,入队列
{
q.push(p->lchild);
}
if(p->rchild)//右孩子不空,入队列
{
q.push(p->rchild);
}
if(p->lchild||p->rchild)count1++;
}
return count1;
}
int preorder_get_leaf_number(BiTree proot)
{
if(proot == NULL)
return 0;
int num = 0;
stack <BiTree> st;
while (proot != NULL || !st.empty())
{
while (proot != NULL)
{
st.push(proot);
proot = proot->lchild;
}
if (!st.empty())
{
proot = st.top();
st.pop();
if(proot->lchild == NULL && proot->rchild == NULL)
num++;
proot = proot ->rchild;
}
}
return num;
}
void ExchangeLeftRight2(BiTree node) {
if(node == NULL)
return ;
BiTree p = node;//指针
stack<BiTree> s;
//Stack<Node> stack = new Stack<Node>();
p = node;
/**
* 首先交换左右子树
* 如果右子树不为空则入栈
* 如果左子树不为空则将指针指向左子树,对左子树进行同样的操作
* 否则,出栈
*/
while(1){
BiTree temp = p->lchild;
p->lchild = p->rchild;
p->rchild = temp;
if(p->rchild !=NULL){//将右节点入栈
s.push(p->rchild);
}
if(p->lchild !=NULL){//指向左节点
p = p->lchild;
}else{
if(s.empty()){//栈为空时结束
break;
}else{
p = s.top();
s.pop();
}
}
}
}
int main()
{
BiTree root;char str[1000];
//cout<<"请输入根节点的值: ";
//root = CreateBiTree();
cout<<"按先序输入二叉树:";
cin>>str;
root = CreateBiTreeNonRecur(str);
if(root!=NULL)cout<<"创建成功"<<endl;
cout<<"先序遍历:";
pre_traverse(root);
cout<<endl;
cout<<"中序遍历:";
in_traverse(root);
cout<<endl;
cout<<"后序遍历:";
beh_traverse(root);
cout<<endl;
cout<<"层次遍历";
int count1=levelOrderTraverse(root);
cout<<endl;
cout<<"深度为:"<<count1<<endl;
int num=preorder_get_leaf_number(root);
cout<<"叶子节点个数为:"<<num<<endl;
cout<<"交换左右子树"<<endl;
ExchangeLeftRight2(root);
cout<<"先序遍历:";
pre_traverse(root);
cout<<endl;
return 1;
}