天勤数据结构笔记——第六章 树与二叉树(大题)

1、基础题

(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;
}

2、思考题

(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)略

 

 

你可能感兴趣的:(数据结构)