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