19、后序非递归遍历二叉树
void PostOrder(BiTree){
BiTree p=T,r=NULL;//标记最近访问过的结点
InitStack(S);
while(p || !StackEmpty(S)){
//一直向左访问
if(p){
push(S,p);
p=p->lchild;
}
//左子树为空,判断是否存在右子树
else{
GetTop(S,p);
if(p->rchild && p->rchild!=r){
p=p->rchild;
push(S,p);
}
//指向右子树的左子树
p=p->lchild;
else{
//右子树也为空
pop(S,p);
visit(p);
r=p;
p=NULL;//结点访问完,重置p指针
}
}
}
}
20、在二叉树中查找值为x的结点,打印出值为x的所有祖先
模板:
void func(BiTree T){
if(T){
(1)//操作一:当我们从上到下访问结点时需要做的操作
func(T->lchild);
(2)
func(T->rchild);
(3)//操作三:当我们从下往上时要做的操作
}
}
因此,我们可以在操作一时让结点入栈,判断结点是否为x,如果是则直接打印栈中元素,否则继续运行下去,直到进行到操作三时让结点出栈
int i;
int top=0;
char path[100];
void allParent(BiTree T,char x){
if(T){
path[top]=T->data;
top++;
if(T->data==x){
for(i=0;i<top;i++)
std::cout<<path[i];
}
allParent(T->lchild,x);
allParent(T->rchild,x);
top--;
}
}
21、层次遍历
利用队列,先让根入队,然后出队,访问出队结点,判断它是否存在左子树和右子树,如果有则让它们入队,接着依次进行下去,如此反复,直到队列为空
void levelOrder(BiTree T){
InitQueue(Q);
BiTree p;
EnQueue(Q,T);
while(!isEmpty(Q)){
DeQueue(Q,p);
visit(p->data);
if(p->lchild)
EnQueue(Q,p->lchild);
if(p->rchild)
Enqueue(Q,p->rchild);
}
22、试给出自下而上、从右到左的层次遍历
恰好与上述层次遍历所求的队列相反,可以使用栈,再出队时先不访问该结点,而是将其压入栈中,最后弹栈访问结点。
void InverseLevel(BiTree T){
if(T){
InitStack(S);
InitQueue(Q);
BiTree p;
EnQueue(Q,T);
while(!isEmpty(Q)){
DeQueue(Q,p);
push(S,p);
if(p->lchild)
EnQueue(Q,p->lchild);
if(p->rchild)
EnQueue(Q,p->rchild);
}
while(!isEmpty(S)){
Pop(S,p);
visit(p->data);
}
}
}
23、求解二叉树的宽度
宽度:最大层结点总数
新定义一个队列,队列元素包含结点指针、以及层数。
typedef struct Qe{
BiTree p;//节点信息
int lv;//层数
}Qe;
int Width(BiTree T){
S Qu[30];
int f,r,max;
f=r=0;
int level;
BiTree q;
if(T){
//根节点入队列
++r;
Qu[r].p=T;
Qu[r].ln=1;
//队不空,则进入循环
while(f<r){
//根节点出队列
++f;
q=Qu[f].p;
level=Qu[f].lv;
if(q->lchild){
++r;
Qu[r].p=q->lchild;
Qu[r].lv=level+1;
}
if(q->rchild){
++r;
Qu[r].p=q->rchild;
Qu[r].lv=level+1;
}
}//层序遍历入队操作完
max=0;
for(int i=0;i<=level;i++){
n=0;
for(int j=0;j<=r;j++){
if(Qu[j].lv==i)
n++;
}
if(n>max)
max=n;
}//在队列中找层数一样的个数
return max;
}else
return 0;
}
24、判断二叉树是否为完全二叉树
依旧是依靠层次遍历
bool Iscomple(BiTree T){
InitQueue(Q);
BiTree p;
if(T){
EnQueue(Q,T);
while(!isEmpty(Q)){
DeQueue(Q,p);//出队
if(p){
EnQueue(Q,p->lchild);
Enqueue(Q,p->rchild);
}else{
while(!isEmpty(Q)){
DeQueue(Q,p);
if(p!=NULL)
return false;
}
}
}
return true;
}else
return false;
}
25、计算二叉树的带权路径长度(叶子节点)
int WPL(BiTree T){
return wpl_preOder(T,0);
}
int wpl_preOrder(BiTree T,int deep){
static int wpl=0;
if(T){
if(T->lchild==NULL&&T->rchild==NULL){
wpl+=deep*T->weight;
if(T->lchild)
wpl_preOrder(T->lchild,deep+1);
if(T->rchild)
wpl_preOrder(T->rchild,deep+1);
}
return wpl;
}
26、将给定的二叉树转化为给定的中缀表达式
用中序遍历解决
void BTreetoE(BiTree T){
BiTreeToExp(T,0);
}
void BiTreeToExp(BiTree T,int deep){
if(T==NULL)
return;
else if(T->lchild==NULL&&T->rchild==NULL)
printf("%s",T->data);
else {
if(deep>1)
printf("(");
BiTreeToExp(T->lchild,deep+1);
printf("%s",T->data);
BiTreeToExp(T->rchild,deep+1);
if(deep>1)
printf(")");
}
}