结构体声明:
//链式二叉树结构体声明
typedef struct BiTNode
{
char ch;
struct BiTNode *Lchild;
struct BiTNode *Rchild;
}BiTNode, *BiTree;
typedef int Status;
typedef BiTree ElemType;
//栈的结构声明
typedef struct
{
ElemType *base;
ElemType *top;
int stacksize;
}SqStack;
递归创建二叉树
//创建二叉树
BiTree CreatBiTree()
{
char i;
BiTree T;
scanf("%c",&i);
if(i == '#')
T = NULL;
else
{
T = (BiTree)malloc(sizeof(BiTNode));
T->ch = i;
T->Lchild = CreatBiTree();
T->Rchild = CreatBiTree();
}
return T;
}
访问函数
Status Visit(char ch)
{
printf("%c\t",ch);
return OK;
}
非递归遍历
自己的
//先序非递归遍历
Status PreOrderTraverse_U(BiTree T, Status(* Visit)(char))
{
SqStack S;
InitStack(S);
Push(S,T);
BiTree p = NULL;
while(S.top != S.base)
{
//结束条件为取不到栈顶元素或者栈顶为空指针
while(GetTop(S,p) && p)
{
//访问节点
if(!Visit(p->ch))
return ERROR;
//压入左孩子
Push(S,p->Lchild);
}
//弹出栈顶空指针
Pop(S,p);
//弹出栈顶上次访问的节点,用p带回
Pop(S,p);
//压入右孩子
if(p)
Push(S,p->Rchild);
else
return 0;
}
}
//中序非递归遍历
Status InOrderTraverse_U(BiTree T, Status(* Visit)(char))
{
SqStack S;
InitStack(S);
Push(S,T);
BiTree p = NULL;
while(S.top != S.base)
{
//向左走到尽头,&& p 可以使空指针退出而不压入它的左指针
while(GetTop(S,p) && p)
{
Push(S,p->Lchild);
}
//空指针退栈
Pop(S,p);
//如果栈不空
if(S.top != S.base)
{
//栈顶元素出栈,用p带回,不可与访问语句交换,因为这句还对空指针p赋值为栈顶元素
Pop(S,p);
//访问结点
if(!Visit(p->ch))
return ERROR;
//压入右指针
Push(S,p->Rchild);
}
}
}
网上的
//中序非递归遍历(差异点:遍历右子树时没有存储当前根指针,直接修改栈顶指针值)
Status InOrderTraverse_U(BiTree T, Status(* Visit)(char)) {
//采用二叉链表存储结构,Visit是对数据元素操作的应用函数。
//中序遍历二叉树T的非递归算法,对每个数据元素调用函数Visit.
InitStack(S) ;
BiTree p = T;
while (p | !StackEmpty(S)) {
if (p) {Push(S, p); p = p->lchild; }// 根指针进栈,遍历左子树
else {
//根指针退栈,访问根结点,遍历右子树
Pop(S, p);
if ( !Visit(p -> data)) return ERROR;
p = p->rchild;
}// else
}// While
return OK;
} // InOrderTraverse
//先序非递归遍历(差异点:相较于自己的,右指针提前入栈(先序时根->左->右,所以右指针应该比左指针先入栈),容易理解,果然自己还需要修炼)
Status PreOrderTraverse_U(BiTree T, Status(* Visit)(char)) {
SqStack S;
InitStack(S);
Push(S,T);
BiTree p = NULL;
while(S.top != S.base)
{
//根指针退栈
Pop(S,p);
//访问根结点
Visit(p -> data)
//如果右子树不空
if(!p -> rchild)
{
//右子树指针入栈
Push(S,p -> rchild)
}
//如果左子树不空
if(!p -> lchild)
{
//左子树指针入栈
Push(S,p -> lchild)
}
}
}