剑指OFFER之二叉树篇

来源:互联网 发布:淘宝公益宝贝好处 编辑:程序博客网 时间:2024/06/05 10:57
#include <stdio.h>#include <malloc.h>#include "common_define.h"#include "jianzhioffer_queue.h"#include "jianzhioffer_stack.h"#include "jianzhioffer_tree.h"void visit(t_elemtype data){    printf("%c ", data);}status create_bitree(struct bitree_node **T){   t_elemtype ch;   char clear_c;   printf("please input ch to create bitree node:");   scanf("%c", &ch);   /* 清空输入缓冲区的方法,在gcc中rewind/fflush这两种方法都不行 */   //rewind(stdin);   //fflush(stdin);   /* 请空输入缓冲区的经典方法,把输入缓冲区的垃圾信息(包括换行)都读走,注意这里的clear_c不能用ch代替,因为后续还要使用到ch */   while ( (clear_c = getchar()) != '\n' && clear_c != EOF);   if (ch == '#')   {       (*T) = NULL;       return OK;   }   else   {       (*T) = (struct bitree_node *)malloc(sizeof(struct bitree_node));         printf("malloc %p\n", (*T));       if(!(*T))       {           printf("%s: malloc failed\n", __FUNCTION__);           return ERROR;       }       (*T)->data = ch;       (void)create_bitree(&((*T)->lchild));       (void)create_bitree(&((*T)->rchild));       return OK;   }}void inorder_traverse(struct bitree_node *T){    if (T)    {        inorder_traverse(T->lchild);        visit(T->data);        inorder_traverse(T->rchild);    }}void preorder_traverse(struct bitree_node *T){    if (T)    {        visit(T->data);        preorder_traverse(T->lchild);        preorder_traverse(T->rchild);    }}void postorder_traverse(struct bitree_node *T){    if (T)    {        postorder_traverse(T->lchild);        postorder_traverse(T->rchild);        visit(T->data);    }}static void swap(struct bitree_node* *left, struct bitree_node* *right){    struct bitree_node *tmp;    tmp = *left;    *left = *right;    *right = tmp;}/* 面试题19: 二叉树的镜像 */void mirror_bitree(struct bitree_node *T){    if (!T)    {        return;    }    if (!T->lchild && !T->rchild)    {        return;    }    swap(&(T->lchild), &(T->rchild));    if (T->lchild)    {        mirror_bitree(T->lchild);    }    if (T->rchild)    {        mirror_bitree(T->rchild);    }}/* 面试题25: 从上到下打印二叉树 */void print_level_traverse(struct bitree_node *T){    struct linked_queue Q;    struct bitree_node *e;    if (T)    {        init_queue(&Q);        push_queue(&Q, T);        while (!queue_empty(Q))        {            pop_queue(&Q, &e);             visit(e->data);                if (e->lchild)            {                push_queue(&Q, e->lchild);            }            if (e->rchild)            {                push_queue(&Q, e->rchild);            }        }    }}int leaf_node(struct bitree_node *T){    if (T)    {        if (!T->lchild && !T->rchild)        {            return 1;        }        else        {            return 0;        }    }    return 0;}/* 面试题25: 二叉树中和为某一值的路径 */struct stack S;void find_path_of_tree_core(struct bitree_node *head, int* sum, int k){    s_elemtype elem;    if (!head)    {        return;    }    else    {        push_stack(&S, head->data);        *sum += (head->data - '0');    }    if ( (*sum == k) && leaf_node(head))    {        printf("\n#################################\n");        //print_stack(S);    }    if (head->lchild)    {        find_path_of_tree_core(head->lchild, sum, k);    }    if (head->rchild)    {        find_path_of_tree_core(head->rchild, sum, k);    }    *sum -= (head->data - '0');    pop_stack(&S, &elem);}void find_path_of_tree(struct bitree_node *head, int k){    int sum = 0;    init_stack(&S);    find_path_of_tree_core(head, &sum, k);}/* 面试题39: 二叉树的深度 */int get_height_of_tree(struct bitree_node *head){    int l_height;    int r_height;    if (!head)    {        return 0;    }    else    {        l_height = get_height_of_tree(head->lchild);        r_height = get_height_of_tree(head->rchild);        return l_height > r_height ? (l_height + 1): (r_height + 1);    }}int B_subof_A_core(struct bitree_node *headA, struct bitree_node *headB){    int result1;    int result2;    if (!headB)    {        return 1;    }    if (!headA)    {        return 0;    }    if (headA->data != headB->data)    {        return 0;    }    result1 = B_subof_A_core(headA->lchild, headB->lchild);    result2 = B_subof_A_core(headA->rchild, headB->rchild);    return result1 && result2;}/* 面试题18: 树B是否为树A的子结构 */int B_subof_A(struct bitree_node *headA, struct bitree_node *headB){    int result = 0;    if (headA && headB)     {       if (headA->data == headB->data)       {           result = B_subof_A_core(headA, headB);        }       if (!result)       {            result = B_subof_A(headA->lchild, headB);        }       if (!result)       {           result = B_subof_A(headA->rchild, headB);       }       return result;    }    else    {        return 0;    }}/* 面试题24:二叉搜索树的后续遍历序列 */bool verify_post_seq_of_BST(int *seq, int n){   int result = TRUE; //默认为TRUE   int i = 0;   int k;   t_elemtype root_data;   if (!seq || n < 0 || n == 0) // 如果没有判断是否存在左子数或右子数,                                // 则n == 0时应该返回TRUE   {       return FALSE;   }   if (n == 1 /* || n == 0 */)   {       return result;   }   root_data = seq[n - 1];   while (seq[i] < root_data)   {       i++;   }   k = i;   while (seq[i] > root_data)   {       i++;   }   printf("k =  %d ,i = %d, n = %d\n", k, i, n);   if (i == (n - 1) )   {        if (k > 0) // 有左分支则处理,没有则不处理,保持原来的判断结果不变        {            result = verify_post_seq_of_BST(seq, k);               }        if (result)        {            if (k < n -1) // 有右分支则处理,没有则不处理,保持原来的判断结果不变            {                result = verify_post_seq_of_BST(seq + k, n - k - 1);            }            return result;        }        else        {            return FALSE;        }   }   else   {       return FALSE;   }}/* 面试题27:二叉搜索树与双向链表 */void print_linked(struct bitree_node *linked_head){    while (linked_head)    {        printf("%c ", linked_head->data);        linked_head = linked_head->rchild;    }}void convert_core(struct bitree_node *head){    struct bitree_node *left_max;     struct bitree_node *right_min;    if (!head)    {        return;    }    if (head->lchild)    {        convert_core(head->lchild);    }    if (head->rchild)    {        convert_core(head->rchild);    }    left_max = head->lchild;    if (left_max)    {        while (left_max->rchild)        {            left_max = left_max->rchild;        }    }    right_min = head->rchild;    if (right_min)    {        while(right_min->lchild)        {            right_min = right_min->lchild;        }    }    if (left_max)    {        left_max->rchild = head;    }    head->lchild = left_max;    if (right_min)     {        right_min->lchild = head;    }    head->rchild = right_min;}struct bitree_node* convert(struct bitree_node *head){    if (!head)    {        return NULL;    }    convert_core(head);    /* 获取转换后的双向链表的链表头, 其实还需要获取链表尾,可以通过函数参数的引用来完成,*     * 但为了程序简单,不喧宾夺主,采用返回值的方法返回链表头                             */    while (head->lchild)    {        head = head->lchild;    }    return head;}/* 面试题6:重建二叉树 */struct bitree_node * recreate_bitree(int *preorder, int *inorder, int n) {    struct bitree_node *root;    int i = 0;    if (!preorder || !inorder || n <= 0)    {        return NULL;    }#if 0    if (n == 1 && preorder[0] != inorder[0])    {        printf("invalid input!\n");        return NULL;    }#endif    root = (struct bitree_node *)malloc(sizeof(struct bitree_node));    if (!root)    {        printf("[%d]: malloc failed\n", __LINE__);        return NULL;    }    root->data = preorder[0];    while (i <= n-1 && inorder[i] != preorder[0])    {        i++;    }    if (i == n)     {        printf("Waring: invalid input!!!\n");        return NULL;    }    root->lchild = recreate_bitree(preorder + 1, inorder, i);    root->rchild = recreate_bitree(preorder + i + 1, inorder + i + 1, n - i - 1);    return root;}

0 0