二叉树相关面试题

  • 树的先序遍历(非递归版本)
void TreePreOrderByLoop(TreeNode* root){
    if(root == NULL)
        return;
    //1.先将根节点入栈
    SeqStack stack;
    SeqStackInit(&stack);
    SeqStackPush(&stack,root);
    //2.循环开始,若栈为空,循环结束
    TreeNode* cur = NULL;
    while(GetTop(&stack,&cur)){
        //取栈顶元素为当前元素
        //出栈
        SeqStackPop(&stack);
        //访问当前元素
        printf("%c ",cur->data);
        //将当前的右子树入栈
        if(cur->rchild != NULL)
            SeqStackPush(&stack,cur->rchild);
        //将当前元素的左子树入栈
        if(cur->lchild != NULL)
            SeqStackPush(&stack,cur->lchild);
    }
    return;
}
  • 树的中序遍历(非递归版本)
void TreeInOrderByLoop(TreeNode* root){
    if(root == NULL)
        return;
    SeqStack stack;
    SeqStackInit(&stack);
    //1.定义一个cur指针指向根节点
    TreeNode* cur = root;
    while(1){
    //循环判定cur是否为空,若不为空,cur入栈,cur指向cur->lchild
        while(cur != NULL){
            SeqStackPush(&stack,cur);
            cur = cur->lchild;
        }
    //若cur为空,取栈顶元素,访问,出栈
    TreeNode* top = NULL;
    int ret = GetTop(&stack,&top);
    if(ret == 0){
        printf("\n");
        return;
    }
    printf("%c ",top->data);
    SeqStackPop(&stack);
    //让cur指向栈顶元素的右子树,重复循环判空过程
    cur = top->rchild;
    }
    return ;
}
  • 树的后序遍历(非递归版本)
void TreePostOrderByLoop(TreeNode* root){
    if(root == NULL)
        return;
    SeqStack stack;
    SeqStackInit(&stack);
    //定义cur指向root
    TreeNode* cur = root;
    TreeNode* pre = NULL;
    //循环判定cur是否为空,若不为空,将cur入栈,cur指向cur->lchild
    while(1){
        while(cur != NULL){
            SeqStackPush(&stack,cur);
            cur = cur->lchild;
        }
    //若cur为空,循环取栈顶元素
    TreeNode* top = NULL;
    int ret = GetTop(&stack,&top);
    if(ret == 0){
        printf("\n");
        return;
    }
    //对栈顶元素进行判定
    //a.若top的rchild和访问的上一个元素是同一元素
    //或top->rchild为空
    //访问栈顶元素,并出栈
    if(top->rchild == NULL || top->rchild == pre){
        printf("%c ",top->data);
        SeqStackPop(&stack);
        pre = top;
    }
    //若不满足上面的条件,cur指向top->rchild
    else{
        cur = top->rchild;
    }
    }
    return;
}
  • 求二叉树的镜像(翻转)
递归版本:
void Swap(TreeNode** a,TreeNode** b){
    TreeNode* tmp = *a;
    *a = *b;
    *b = tmp;
}

void TreeMirror(TreeNode* root){
    if(root == NULL)
        return;
    Swap(&root->lchild,&root->rchild);
    TreeMirror(root->lchild);
    TreeMirror(root->rchild);
    return;
}

非递归版本:

void TreeMirrorByLoop(TreeNode* root){
    //层序遍历实现
    if(root == NULL)
        return;
    SeqQueue q;
    SeqQueueInit(&q);
    SeqQueuePush(&q,root);
    TreeNode* cur = NULL;
    while(SeqQueueFront(&q,&cur)){
        Swap(&cur->lchild,&cur->rchild);
        SeqQueuePop(&q);
        if(cur->lchild != NULL){
            SeqQueuePush(&q,cur->lchild);
        }
        if(cur->rchild != NULL){
            SeqQueuePush(&q,cur->rchild);
        }
    }
    return;
}
  • 判断一棵树是否为完全二叉树
int IsCompleteTree(TreeNode* root){
    if(root == NULL)
        return 0;
    SeqQueue q;
    SeqQueueInit(&q);
    SeqQueuePush(&q,root);
    TreeNode* cur = NULL;
    int start_step_two = 0;
    while(SeqQueueFront(&q,&cur)){
        SeqQueuePop(&q);
        if(start_step_two == 0){
            //阶段一
            if(cur->lchild != NULL && cur->rchild != NULL){
                //同时具备左右子树
                SeqQueuePush(&q,cur->lchild);
                SeqQueuePush(&q,cur->rchild);
            }
            else if(cur->lchild == NULL && cur->rchild != NULL)
                //只有右子树
                return 0;
            else if(cur->lchild != NULL && cur->rchild == NULL){
                //只有左子树
                start_step_two = 1;
                SeqQueuePush(&q,cur->lchild);
            }
            else{//无左右子树
            start_step_two = 1;
        }
    }
    else{//阶段二
        if(cur->lchild == NULL && cur->rchild == NULL);
        else 
            return 0;
    }
    }
    return 1;
}
  • 根据前序遍历和中序遍历重建二叉树
size_t Find(TreeNodeType array[],size_t left,size_t right,TreeNodeType to_find){
    size_t i = left;
    for(;i < right;++i){
        if(array[i] == to_find){
            return i;
        }
    }
    return (size_t)-1;
}

TreeNode* _TreeRebuild(TreeNodeType pre_order[],size_t pre_order_size,size_t* pre_order_index,
    if(in_order_left >= in_order_right){
        //无效区间,当前子树的中序遍历结果为空,即这棵子树为空树
        return NULL;
    }
    if(pre_order_index == NULL || *pre_order_index >= pre_order_size){
        return NULL;
    }
    //根据先序遍历结果取出当前值,基于该值构建一个节点,new_node相当于当前子树的根节点
    TreeNode* new_node = CreateTreeNode(pre_order[*pre_order_index]);
    //查找一下当前节点在中序序列中的位置
    size_t cur_root_in_order_index = Find(in_order,in_order_left,in_order_right,new_node->data
    assert(cur_root_in_order_index != (size_t)-1);
    ++(*pre_order_index);
    new_node->lchild = _TreeRebuild(pre_order,pre_order_size,pre_order_index,in_order,in_order
    new_node->rchild = _TreeRebuild(pre_order,pre_order_size,pre_order_index,in_order,cur_root
    return new_node;
}

TreeNode* TreeRebuild(TreeNodeType pre_order[],TreeNodeType in_order[],size_t size){
    size_t pre_order_index = 0;
    size_t in_order_left = 0;
    size_t in_order_right = size;
    return _TreeRebuild(pre_order,size,&pre_order_index,in_order,in_order_left,in_order_right)
}


测试函数:

int main(){
void TestPreOrderByLoop(){
    PRINT_HEAD;
    TreeNodeType data[] = "abd##eg###c#f##";
    TreeNode* root = TreeCreate(data,sizeof(data)/sizeof(data[0])-1,'#');
    printf("先序遍历为:");
    TreePreOrderByLoop(root);
    printf("\n");
}

void TestInOrderByLoop(){
     PRINT_HEAD;
     TreeNodeType data[] = "abd##eg###c#f##";
     TreeNode* root = TreeCreate(data,sizeof(data)/sizeof(data[0])-1,'#');
     printf("中序遍历为:");
     TreeInOrderByLoop(root);
     printf("\n");

}

void TestPostOrderByLoop(){
     PRINT_HEAD;
     TreeNodeType data[] = "abd##eg###c#f##";
     TreeNode* root = TreeCreate(data,sizeof(data)/sizeof(data[0])-1,'#');
     printf("后序遍历为:");
     TreePostOrderByLoop(root);
     printf("\n");
}

void TestMirror(){
     PRINT_HEAD;
     TreeNodeType data[] = "abd##eg###c#f##";
     TreeNode* root = TreeCreate(data,sizeof(data)/sizeof(data[0])-1,'#');
     TreeMirror(root);
     printf("先序遍历为:");
     TreePreOrderByLoop(root);
     printf("\n");
     printf("中序遍历为:");
     TreeInOrderByLoop(root);
     printf("后序遍历为:");
     TreePostOrderByLoop(root);
     printf("层序遍历为:");
     TreeLevelOrder(root);
     printf("\n");
}

void TestMirrorByLoop(){
     PRINT_HEAD;
     TreeNodeType data[] = "abd##eg###c#f##";
     TreeNode* root = TreeCreate(data,sizeof(data)/sizeof(data[0])-1,'#');
     TreeMirror(root);
     printf("先序遍历为:");
     TreePreOrderByLoop(root);
     printf("\n");
     printf("中序遍历为:");
     TreeInOrderByLoop(root);
     printf("后序遍历为:");
     TreePostOrderByLoop(root);
     printf("层序遍历为:");
     TreeLevelOrder(root);
     printf("\n");
}

void TestIsCompleteTree(){
    PRINT_HEAD;
    TreeNodeType data[] = "abd##eg###c#f##";
    TreeNode* root = TreeCreate(data,sizeof(data)/sizeof(data[0])-1,'#');
    int ret = IsCompleteTree(root);
    printf("ret = %d\n",ret);    
}

void TestRebuild(){
    PRINT_HEAD;
    TreeNodeType pre_order[] = "ABDEGCF";
    TreeNodeType in_order[] = "DBGEACF";
    size_t size = strlen(pre_order);
    TreeNode* root = TreeRebuild(pre_order,in_order,size);
    printf("后序遍历结果为:");
    TreePostOrder(root);
    printf("\n");
    printf("层序遍历结果为:");
    TreeLevelOrder(root);
    printf("\n");
}


int main(){
    TestInit();
    TestPreOrder();
    TestInOrder();
    TestPostOrder();
    TestLevelOrder();
    TestCreate();
    TestClone();
    TestDestroy1();
    TestDestroy2();
    TestSize();
    TestLeafSize();
    TestLevelSize();
    TestHeight();
    TestFind();
    TestParent();
    TestLChild();
    TestRChild();
    TestPreOrderByLoop();
    TestInOrderByLoop();
    TestPostOrderByLoop();
    TestMirror();
    TestMirrorByLoop();
    TestIsCompleteTree();
    TestRebuild();
}

结果演示:





评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值