[置顶] 剑指OFFER之二叉树篇

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

你可能感兴趣的:([置顶] 剑指OFFER之二叉树篇)