• Careercup | Chapter 4


    二叉查换树,左孩子小于等于根,右孩子大于根。 

    完全二叉树,除最后一层外,每一层上的节点数均达到最大值;在最后一层上只缺少右边的若干结点。 complete binary tree

    满二叉树,完美二叉树是全部结点数达到最大的二叉树。perfect binary tree, full binary tree.

    平衡二叉树,左右子树的高度在一定范围内。 

    二叉查找树(Binary Search Tree),也称二叉搜索树、有序二叉树(ordered binary tree),排序二叉树(sorted binary tree),是指一棵空树或者具有下列性质的二叉树:

    1. 若任意节点的左子树不空,则左子树上所有结点的值均小于或等于它的根结点的值;
    2. 任意节点的右子树不空,则右子树上所有结点的值均大于它的根结点的值;
    3. 任意节点的左、右子树也分别为二叉查找树。
    4. 没有键值相等的节点(no duplicate nodes)。

    在二叉查找树删去一个结点,分三种情况讨论:

    • 若*p结点为叶子结点,即PL(左子树)和PR(右子树)均为空树。由于删去叶子结点不破坏整棵树的结构,则只需修改其双亲结点的指针即可。
    • 若*p结点只有左子树PL或右子树PR,此时只要令PL或PR直接成为其双亲结点*f的左子树(当*p是左子树)或右子树(当*p是右子树)即可,作此修改也不破坏二叉查找树的特性。
    • 若*p结点的左子树和右子树均不空。在删去*p之后,为保持其它元素之间的相对位置不变,可按中序遍历保持有序进行调整,可以有两种做法:其一是令*p的左子树为*f的左/右(依*p是*f的左子树还是右子树而定)子树,*s为*p左子树的最右下的结点,而*p的右子树为*s的右子树;其二是令*p的直接前驱(in-order predecessor)或直接后继(in-order successor)替代*p,然后再从二叉查找树中删去它的直接前驱(或直接后继)。

    4.1 Implement a function to check if a binary tree is balanced. For the purposes of this question, a balanced tree is defined to be a tree such that the heights of the two subtrees of any node never differ by more than one.

    4.2 Given a directed graph, design an algorithm to find out whether there is a route between two nodes.

    BFS或者DFS就行了,不过BFS可以避免在单条路径上挖得太深。

    4.3 Given a sorted (increasing order) array with unique integer elements, write an algorithm to create a binary search tree with minimal height

    4.4 Given a binary tree, design an algorithm which creates a linked list of all the nodes at each depth (e.g., if you have a tree with depth D, you'll have D linked lists).

    BFS或者DFS都可以。注意的是,DFS虽然会用额外的O(lgn)的栈空间,但是整体的空间复杂度还是O(n)。

    4.5 Implement a function to check if a binary tree is a binary search tree.

    。BST要和中序遍历联系在一起。

    4.6  Write an algorithm to find the 'next'node (i.e., in-order successor) of a given node in a binary search tree. You may assume that each node has a link to its parent.

    如果有root结点,直接用中序遍历记录pre结点就可以做的。如果只有结点,那么需要分情况。

    4.7 Design an algorithm and write code to find the first common ancestor of two nodes in a binary tree. Avoid storing additional nodes in a data structure. NOTE: This is not necessarily a binary search tree.

    leetcode上的博文,讲得很仔细。这道题很经典,尤其是有parent结点时的解法,类似求intersect linklist的交叉点。

    4.8 You have two very large binary trees: Tl, with millions of nodes, and T2, with hundreds of nodes. Create an algorithm to decide if T2 is a subtree of Tl. A tree T2 is a subtree of Tl if there exists a node n in Tl such that the subtree of n is identical to T2. That is, if you cut off the tree at node n, the two trees would be identical.

    这道题可以穷搜,也可以基于pre-order和in-order的travesal串,用子串查找。

    4.9 You are given a binary tree in which each node contains a value. Design an algorithm to print all paths which sum to a given value. The path does not need to start or end at the root or a leaf.

    只能穷搜了。

      1 struct TreeNode {
      2     TreeNode *left;
      3     TreeNode *right;
      4     TreeNode *parent;
      5     int val;
      6     TreeNode(int v):val(v),left(NULL),right(NULL),parent(NULL) {}
      7 };
      8 
      9 // 4.6
     10 TreeNode* findInorderNext(TreeNode* node) {
     11     if (node == NULL) {
     12         return NULL;
     13     } else if (node->right) {
     14         node = node->right;
     15         while (node->left) node = node->left;
     16         return node;
     17     } else {
     18         while (node->parent && node->parent->left != node) node = node->parent;
     19         return node->parent;
     20     }
     21 }
     22 
     23 TreeNode* findPreordeNext(TreeNode* node) {
     24     if (node == NULL) {
     25         return NULL;
     26     } else if (node->left) {
     27         return node->left;
     28     } else if (node->right) {
     29         return node->right;
     30     } else {
     31         while (node->parent && node->parent->right == node) {
     32             node = node->parent;
     33         }
     34         if (node->parent) return node->parent->right;
     35         else return NULL;
     36     }
     37 }
     38 
     39 TreeNode* findPostorderNext(TreeNode* node) {
     40     if (node == NULL || node->parent == NULL) {
     41         return NULL;
     42     } else if (node->parent->right == node || node->parent->right == NULL) { // right subtree
     43         return node->parent;
     44     } else {
     45         node = node->parent->right;
     46         while (node->left) node = node->left;
     47         return node;
     48     }
     49 }
     50 
     51 
     52 // 4.7 (1) p, q in the BST, O(h) runtime
     53 TreeNode* LCAInBST(TreeNode *root, TreeNode *p, TreeNode *q) {
     54     if (!root || !p || !q) return NULL;
     55     if (max(p->val, q->val) < root->val) {
     56         return LCAInBST(root->left, p, q);
     57     } else if (min(p->val, q->val) > root->val) {
     58         return LCAInBST(root->right, p, q);
     59     } else {
     60         return root;
     61     }
     62 }
     63 
     64 // 4.7 (2.1) p, q may not in the tree, this is just a binary tree
     65 int matchCount(bool pExisted, bool qExisted) {
     66     int m = 0;
     67     if (pExisted) m++;
     68     if (qExisted) m++;
     69     return m;
     70 }
     71 TreeNode* LCAInBT(TreeNode *root, TreeNode *p, TreeNode *q, bool &pExisted, bool &qExisted) {
     72     if (!root) return NULL;
     73 
     74     TreeNode* ret = LCAInBT(root->left, p, q, pExisted, qExisted);
     75     int lm = matchCount(pExisted, qExisted);
     76     if (lm == 2) return ret; // p, q are in the left subtree
     77     ret = LCAInBT(root->right, p, q, pExisted, qExisted);
     78     int rm = matchCount(pExisted, qExisted);
     79     if (rm == 2) { // p, q are found
     80         if (lm == 1) return root; //p, q are in different subtree, thus return root
     81         else return ret; // lm == 0, p, q are in the right subtree
     82     }
     83     if (root == p) pExisted = true;
     84     if (root == q) qExisted = true;
     85     if (pExisted && qExisted) return root; // if q is a child of q (or, q is a child of p)
     86     return NULL; // if p or q is not existed 
     87 }
     88 
     89 // 4.7(2.2) the parent node is available
     90 int getHeight(TreeNode* p) {
     91     int h = 0;
     92     while (p) {
     93         p = p->parent;
     94         h++;
     95     }
     96     return h;
     97 }
     98 
     99 TreeNode* LCAInBT(TreeNode *p, TreeNode *q) {
    100     if (!p || !q) return NULL;
    101     int h1 = getHeight(p);
    102     int h2 = getHeight(q);
    103     if (h1 > h2) {
    104         swap(p, q);
    105         swap(h1, h2);
    106     }
    107     for (int i = 0; i < h2 - h1; ++i) {
    108         q = q->parent;
    109     }
    110 
    111     while (p && q) {
    112         if (p == q) return p;
    113         p = p->parent;
    114         q = q->parent;
    115     }
    116     return NULL;
    117 }
  • 相关阅读:
    Java && Eclipse使用中的问题
    Java使用的扩展
    Java的基本使用之多线程
    Java的基本使用之反射
    Java的基本使用之IO
    Java的基本使用之异常处理
    CSS中的line-height和vertical-height
    Java的基本使用之多线程
    跟进记录
    将文件从已Root Android手机中copy出来的几个cmd窗口命令
  • 原文地址:https://www.cnblogs.com/linyx/p/3782607.html
Copyright © 2020-2023  润新知