结构树模型(遍历)
先序,中序,后序遍历的递归算法
typedef struct node{
ElemType data;
struct node *lchild;
struct node *rchild;
} BTNode; //声明二叉链的结构类型
void PreOrder(BTNode *b) //先序遍历
{
if(b != NULL)
{
printf("%c",b->data);
PreOrder(b->lchild);
PreOrder(b->rchild);
}
}
void InOrder(BTNode *b) //中序遍历
{
if(b != NULL)
{
InOrder(b->lchild);
printf("%c",b->data);
InOrder(b->rchild);
}
}
void PostOrder(BTNode *b) //后序遍历
{
if(b != NULL)
{
PostOrder(b->lchild);
PostOrder(b->rchild);
printf("%c",b->data);
}
}
先序,中序,后序遍历的非递归算法(用栈实现)
typedef struct node{
ElemType data;
struct node *lchild;
struct node *rchild;
} BTNode; //声明二叉链的结构类型
void PreOrderL(BTNode *b)//先序遍历——————法一
{
BTNode *p;
SqStack *st; //定义一个栈
InitStack(st);//初始化栈指针
if(b != NULL)
{
Push(st,b);//将b指向的根节点进栈
while(!StackEmpty(st))
{
Pop(st,p);//将栈顶元素出栈,且保留栈顶元素于指针p之中
printf("%c",p->data);
if(p->rchild != NULL)//进栈顺序先入后出,因此在先序遍历之中应将右孩子结点先进行入栈操作,再将左孩子进行入栈操作以保证完成先左子树后右子树的先序遍历操作
{
Push(st,p->rchild);
}
if(p->lchild != NULL)
{
Push(st,p->lchild);
}
}
printf("\n");
}
DestroyStack(st);
}
void PreOrdernormal(BTNode *b)//先序遍历——————法二
{
BTNode *p;
SqStack *st;
InitStack(st);
p = b;
while(!StackEmpty(st) || p != NULL)//栈空且p指向了NULL的时候,所有结点访问完成,算法结束
{
while(p != NULL)
{
printf("%c",p->data);
Push(st,p);
p = p->lchild;
}
if(!StackEmpty(st))//栈不空的时候,说明目前的栈顶元素没有左子树,但是可能存在右子树
{
Pop(st,p);//先出栈后处理
p = p->rchild;
}
printf("\n");
DestroyStack(st);
}
}
void InOrdernormal(BTNode *b)//中序遍历
{
BTNode *p;
SqStack *st;
InitStack(st);
p = b;
while(!StackEmpty(st) || p != NULL)
{
while(p != NULL)
{
Push(st,p);
p = p->lchild;
}
if(!StackEmpty(st))//栈不空的时候,说明目前的栈顶元素没有左子树,但是可能存在右子树
{
Pop(st,p);
printf("%c",p->data);
p = p->rchild;
}
}
printf("\n");
DestroyStack(st);
}
void PostOrdernormal(BTNode *b)
{
BTNode *p,*r;
bool flag;
SqStack *st;
IninStack(st);
p = b;
do
{
while(p != NULL)//将结点p的所有的左下结点入栈
{
Push(st,p);//结点p进栈(起始时是栈顶元素入栈)
p = p->lchild;
}
r = NULL;//r指向刚访问的结点,开始时置于NULL
flag = true;//为True时,表示正在处理栈顶结点
while(!StackEmpty(st) && flag)
{
GetTop(st,p);//取得栈顶当前元素
if(p->rchild == r)//若p的右孩子为空或是为刚访问过的结点
{
printf("%c",p->data);
Pop(st,p);
r = p;
}
else
{
p = p->rchild;
flag = false;
}
}
}while(!StackEmpty(st));
printf("\n");
DestroyStack(st);
}
层次遍历(基本)(队列模型)
void LevelOrder(BTNode *b)
{
BTNode *p;
SqQueue *qu;
InitQueue(qu);//初始化队列
enQueue(qu,b);//根节点进入队列
while(!QueueEmpty(qu))//在队列不空的前提下进行循环处理
{
deQueue(qu,p);//出队结点p
printf("%c",p->data);
if(p->lchild != NULL)//判断出队结点p有没有孩子结点,先对左孩子结点进行入队操作,再对右孩子结点进行入队操作
{
enQueue(qu,p->lchild);
}
if(p->rchild != NULL)
{
enQueue(qu,p->rchild);
}
}
DestroyQueue(qu);//销毁队列
}
层次遍历(分层次)(队列模型)
void LevelOrdernormal(BTNode *b)
{
BTNode *p;
SqQueue *qu;
InitQueue(qu);
int curl = 1;//表达当前的层次,初始化为1,表示当前为第一层
enQueue(qu,b);
while(!QueueEmpty(qu))
{
printf("第%d层:",curl);
int cnt = Count(qu);//求当前层次的结点的个数
for(int i=0;i<cnt;i++)
{
deQueue(qu,p);//出队结点p
printf("%c",p->data);
if(p->lchild != NULL)//判断出队结点p有没有孩子结点,先对左孩子结点进行入队操作,再对右孩子结点进行入队操作
{
enQueue(qu,p->lchild);
}
if(p->rchild != NULL)
{
enQueue(qu,p->rchild);
}
}
curl++;//当前层次访问完成,进入下一层
printf("\n");
}
DestroyQueue(qu);
}
求当前层次的结点的个数Count(qu)
void Lnodenum(BTNode *b,int h,int k,int &n)
{
if(b == NULL)
{
return;
}
else
{
if(h == k)
{
n++;
}
else if(h<k)
{
Lnodenum(b->lchild,h+1,k,n);
Lnodenum(b->rchild,h+1,k,n);
}
}
}
//其中h表示b所指的结点层次,n是k层的元素个数,初始调用:int n = 0;Lnodenum(b,1,k,n);