zoukankan      html  css  js  c++  java
  • 一颗完全二叉树,求其结点个数

    网上看了很多人的答案,都说最优解是o(n),想到了一种更快的算法,复杂度是O(lgn的平方),就是对左右子树进行二分,找最后一层的最右边那个结点即可:


    #include <iostream>
    #include <cmath>
    #include <stdlib.h>
    
    using namespace std;
    
    struct Node {
      Node* left;
      Node* right;
      ~Node() {
        if (left) {
          delete left;
          left = NULL;
        }
        if (right) {
          delete right;
          right = NULL;
        }
      }
    };
    
    int GetDepth(Node* root) {
      int depth = 0;
      while (root) {
        depth++;
        root = root->left;
      }
      return depth;
    }
    
    void GetMostRightDepthAndIndex(Node* root, int* depth, int* index) {
      while (root) {
        if (root->right) {
          root = root->right;
          *index = (*index - 1) * 2;
          *index += 2;
          *depth += 1;
        } else if (root->left) {
          root = root->left;
          *index = (*index - 1) * 2;
          *index += 1;
          *depth += 1;
        } else {
          return;
        }
      }
    }
    
    void GetMostLeftDepthAndIndex(Node* root, int* depth, int* index) {
      while (root) {
        if (root->left) {
          root = root->left;
          *index = (*index - 1) * 2;
          *index += 1;
          *depth += 1;
        }
        else if (root->left) {
          root = root->right;
          *index = (*index - 1) * 2;
          *index += 2;
          *depth += 1;
        } else {
          return;
        }
      }
    }
    
    void GetNodeNum(Node* root, int cur_depth, int cur_index,
        int* node_num, int max_depth) {
      if (!root->left) {
        if (cur_depth - 1 >= 1) {
          *node_num += pow(2, cur_depth - 1) - 1;
        }
        *node_num += cur_index;
        return;
      }
      int ml_depth = root->left ? cur_depth + 1 : cur_depth;
      int ml_index = (cur_index - 1) * 2 + 1;
      int mr_depth = root->right ? cur_depth + 1 : cur_depth;
      int mr_index = (cur_index - 1) * 2 + 2;
      GetMostRightDepthAndIndex(root->left, &ml_depth, &ml_index);
      GetMostLeftDepthAndIndex(root->right, &mr_depth, &mr_index);
      if (ml_depth == mr_depth) {
        if (ml_depth == max_depth) {
          GetNodeNum(root->right, cur_depth + 1, (cur_index - 1) * 2 + 2,
              node_num, max_depth);
        } else if (ml_depth < max_depth) {
          GetNodeNum(root->left, cur_depth + 1, (cur_index - 1) * 2 + 1,
              node_num, max_depth);
        } else {
          std::cout << "illegal tree";
          exit(1);
        }
      } else if (ml_depth > mr_depth) {
        if (ml_depth == max_depth && mr_depth == max_depth - 1) {
          *node_num = pow(2, ml_depth - 1) - 1 + ml_index;
        }
      } else {
        std::cout << "illegal tree";
        exit(1);
      }
    }
    
    int main() {
      /* Input: create a  */
      // depth 1
      Node* root = new Node();
      // depth 2
      root->left = new Node();
      root->right = new Node();
      // depth 3
      root->left->left = new Node();
      root->left->right = new Node();
      root->right->left = new Node();
      root->right->right = new Node();
      // depth 4
      root->left->left->left = new Node();
      root->left->left->right= new Node();
      root->left->right->left = new Node();
      root->left->right->right = new Node();
      root->right->left->left = new Node();
      root->right->left->right = new Node();
      root->right->right->left = new Node();
      root->right->right->right = new Node();
      // depth 5
      root->left->left->left->left = new Node();
    
      int root_depth = 1;
      int root_index = 1;
      int max_depth = GetDepth(root);
      int node_num = 0;
      GetNodeNum(root, root_depth, root_index, &node_num, max_depth);
      std::cout << "node_num = " << node_num << endl;
      delete root;
    }




  • 相关阅读:
    微软官方中英文Office2010SP1直接下载地址
    开源协议GUN LGPL
    VS2008安装失败!Microsoft Visual Studio Web 创作组件
    新的类型转换操作符(Type Conversion Operators)
    开源协议GNU GPL
    Visual Studio Ultimate 2012 RC 英文版
    两种老公,两种人生。
    开源协议Apache Licence 2.0
    VS2010 关于 CVT1100 和 LNK1123 的解决办法
    Apache Flink Streaming(DataStream API)
  • 原文地址:https://www.cnblogs.com/riskyer/p/3235343.html
Copyright © 2011-2022 走看看