(1)略
(2)采用层次遍历,visit(q); 改为 count++;
void level(BTNode *p,int &count){
count=0;
int front=rear=0;
BTNode *que[maxSize];
BTNode *q;
if(p!=NULL){
//根结点入队
rear=(rear+1)%maxSize;
que[rear]=p;
while(front!=rear){
//结点出队
front=(front+1)%maxSize;
q=que[front];
count++;
if(q->lchild!=NULL){
//左孩子入队
rear=(rear+1)%maxSize;
que[rear]=q->lchild;
}
if(q->rchild!=NULL){
//右孩子入队
rear=(rear+1)%maxSize;
que[rear]=q->rchild;
}
}
}
}
(3)visit(q);改为判断其是否是叶子结点,再count++
void level(BTNode *p,int &count){
count=0;
int front=rear=0;
BTNode *que[maxSize];
BTNode *q;
if(p!=NULL){
//根结点入队
rear=(rear+1)%maxSize;
que[rear]=p;
while(front!=rear){
//结点出队
front=(front+1)%maxSize;
q=que[front];
if(q->lchild==NULL&&q->rchild==NULL)
count++;
if(q->lchild!=NULL){
//左孩子入队
rear=(rear+1)%maxSize;
que[rear]=q->lchild;
}
if(q->rchild!=NULL){
//右孩子入队
rear=(rear+1)%maxSize;
que[rear]=q->rchild;
}
}
}
}
(4)需要确定两件是:判断出叶子结点,要按从左往右的顺序。由于三种遍历中叶子结点的序列不变。这里就选先序遍历。
void preorder(BTNode *p,BTNode *head,BTNode *tail){
if(p!=NULL){
BTNode *stack[maxSize];
BTNode *q,*r;
int top=-1,first=0;
stack[++top]=p;
while(top!=-1){
q=stack[top--];
if(q->rchild==NULL&&q->lchild==NULL){
if(!first){
head=q;tail=q;r=q;
first=1;
}else{
r->rchild=q;
r=q;tail=q;
}
}
if(q->rchild)
stack[++top]=q->rchild;
if(q->lchild)
stack[++top]=q->lchild;
}
}
}
(5)遍历的时候给parent指针赋值
void fuzhi(BTNode *p){
if(p!=NULL){
BTNode *stack[maxSize],*q;
int top=-1;
stack[++top]=p;
p->parent=NULL;
while(top!=-1){
q=stack[top--];
if(q->rchild!=NULL){
q->rchild->parent=p;
stack[++top]=q->rchild;
}
if(q->lchild!=NULL){
q->lchild->parent=p;
stack[++top]=q->lchild;
}
if(q->rchild==NULL&&q->lchild==NULL){
//叶结点
BTNode *r=q;
while(r!=NULL){
print(r->data);
r=r->parent;
}
}
}
}
}
(6)由于是满二叉树的先序遍历,故去掉根节点(第一个结点)剩下偶数个结点,前半部分是左子树的序列,后半部分是右子树的序列。只需将根结点移到最后,然后递归地处理左右子树部分。
//pre是序列数组,pos是转变后的数组
void change(char pre[],int L1,int R1,char pos[],int L2,int R2){
if(L1<=R1){
pos[R2]=pre[L1];
change(pre,L1+1,(L1+1+R1)/2,pos,L2,(L2+R2-1)/2);
change(pre,(L1+3+R1)/2,R1,pos,(L2+R2+1)/2,R2-1);
}
}
(7)可以在存储结构中添加一个层号信息。但此处用标准答案的先序遍历的递归算法
int L=1;
void leno(BTNode *p,char x){
if(p!=NULL){
if(p->data==x)
cout<lchild,x);
leno(p->rchild,x);
L--;
}
}
(8)略
(9)入栈序列相当于先序遍历顺序,出栈序列相当于中序遍历顺序。先序和中序能唯一确定二叉树。
(10)在先序遍历的递归算法上改动一下
void doubleorder(BTNode *p){
if(p!=NULL){
visit(p);
doubleorder(p->lchild);
visit(p);
doubleorder(p->rchild);
}
}
(11)设中序线索二叉树的类型为TBTNode InThTree
1)t 结点的子树上中序遍历的最后一个结点,就是 t 结点下最右边的结点。另一个说法:只要结点下面有右子树就遍历下去,直到右子树为空。
TBTNode* inLast(TBTNode *t){
TBTNode *p=t;
while(p && p->rtag==0){
p=p->rchild;
}
return p;
}
2)t子树中序下的前驱,若t有左线索,则该左线索就是前驱;若t无左线索,则其左子树中中序的最后一个结点即为它的中序前驱。
TBTNode* inPrior(TBTNode *t){
TBTNode *p=t->lchild;//p要么是左子树,要么是左线索
if(p && !t->ltag){//p是左子树的情况下,找出最右结点
p=inLast(p);
}
return p;
}
(1)这题除了设parent指针外,还可以用栈。每遍历到一个结点就入栈,遍历到根结点后打印栈。然后退回上一层的时候,需要退回栈顶指针一步。
int i;
int top=-1;
char pathsetback[maxSize];
void allPath(BTNode *p){
if(p!=NULL){
pathsetback[++top]=p->data;
if(p->lchild==NULL && p->rchild==NULL){
for(i=0;ilchild);
allPath(p->rchild);
--top;
}
}
(2)略