判斷完全二叉樹節點個數

判斷完全二叉樹節點個數

判斷方法

  • 使用遞歸
  • 找到完全二叉樹的總高度(找到左子樹樹的總高度)
  • 從root開始,
    1. 如果當前節點層數等於樹的高度返回1,也就是此節點與其子樹的節點一共只有一個
    2. 如果右子樹的左邊界的高度與樹的總高度相同,那麼左子樹爲滿二叉樹,返回左子樹節點個數+當前節點(1個)+右子樹節點數
    3. 右子樹左邊界不到整棵樹的深度,那麼右子樹爲滿二叉樹,返回右子樹節點個數+當前節點(1個)+左子樹節點數

代碼

  //節點
  struct Node {
      int value;
      Node* parent;
      Node* left;
      Node* right;
  
      Node(int v = 0): value(v), parent(nullptr), left(nullptr), right(nullptr) {}
  };

  //銷燬二叉樹
  void destroy_tree(Node* root) {
      if (root == nullptr) {
          return;
      }
  
      destroy_tree(root->left);
      destroy_tree(root->right);
  
      delete root;
  }

  //找到左子樹樹的總高度
  int get_left_level(Node*node, int level) {
      while (node != nullptr) {
          level++;
          node = node->left;
      }
      return level - 1;
  }
  
  //二分搜索
  int bs(Node* node, int level, int h) {
      //level == height,節點個數爲1
      if (level == h) {
          return 1;
      }
      //右子樹左邊界到了整棵樹的深度,左子樹一定是滿的
      //返回左子樹節點個數+當前節點(1個)+右子樹節點數
      if (get_left_level(node->right, level + 1) == h) {
          return ((1 << (h - level)) + bs(node->right, level + 1, h));
      } else {
          //右子樹左邊界不到整棵樹的深度
          //右子樹高度比左子樹少一
          //返回右子樹節點個數+當前節點(1個)+左子樹節點數
          return ((1 << (h - level - 1)) + bs(node->right, level + 1, h));
      }
  }
  
  int node_nums(Node* node) {
      if (node == nullptr) {
          return 0;
      }
      return bs(node, 1, get_left_level(node, 1));
  }
  
  int main(void)
  {
      //創建一顆滿樹
      Node* head1 = new Node(0);
      Node* node11 = new Node(1);
      Node* node12 = new Node(2);
      Node* node13 = new Node(3);
      Node* node14 = new Node(4);
      Node* node15 = new Node(5);
      head1->left = node11;
      head1->right = node12;
      node11->left = node13;
      node11->right = node14;
      node12->left = node15;
  
      std::cout << node_nums(head1) << std::endl;
  
      destroy_tree(head1);
      return 0;
  }
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章