求一棵完全二叉树的节点数(不通过遍历)

分析:

完全二叉树特点:完全二叉树的倒数第二层一定全部都是满的

步骤

1、先求出这颗树的高度

2、在求根结点的右子树的高度(找根结点右子树的最左结点)

3、这样就会出现两种情况,一种是左子树的高度和右子树的高度相等,则说明左子树是满二叉树,可用公式求出,再把这个节点的右孩子节点当做根结点进行递归就可以求出整个树的结点数;第二种是右子树的高度比左子树小1,这个时候巧了,右子树也是一满二叉树,只不过比左子树的高度小1而已,也通过递归来实现

这样就通过类似二分的方法来求出树的结点数

代码:

Tree.h

#pragma once

#include <vector>
#include <math.h>

template<class T>
struct Node
{
	T _data;
	Node<T>* _left;
	Node<T>* _right;
	Node(const T& x=T())
		:_left(NULL)
		, _right(NULL)
		, _data(x)
	{}
};

template<class T>
class CompleteBinaryTree
{
	typedef Node<T> Node;
public:
	CompleteBinaryTree()
	{}
	CompleteBinaryTree(T *arr,size_t size)
	{
		int index = 0;
		_root = CreateTree(index , arr, size);
	}
public:
	//求完全二叉树的节点数
	size_t Count()
	{
		size_t count = 0;
		int hight = Hight();/先求出这颗完全二叉树的高度
		return _Count(_root,count,hight);
	}
	size_t Hight()
	{
		return SubHight(_root);
	}
	size_t SubHight(Node* root)
	{
		size_t hight = 0;
		while (root){
			++hight;
			root = root->_left;
		}
		return hight;
	}
protected:
	//根据先序序列,建好的树不一定是完全二叉树,测试的时候给的是完全二叉树
	Node* CreateTree(int& i,T* arr,size_t size)
	{
		while (i < size){
			if (arr[i] == ‘#‘)
				return NULL;
			Node* root = new Node(arr[i]);
			root->_left = CreateTree(++i, arr, size);
			root->_right = CreateTree(++i, arr, size);
			return root;
		}
		return NULL;
	}
	size_t _Count(Node* root, size_t& size, size_t hight)
	{
		size_t count = 0;
		if (root){
			size_t subrighthight = SubHight(root->_right);
			if (subrighthight == hight - 1){//左子树是满二叉树
				size += pow(2.0, (hight - 1)) - 1 + 1;
				size += _Count(root->_right, count, --hight);
			}
			else{
				size += pow(2.0, (hight - 2)) - 1 + 1;
				size += _Count(root->_left, count, --hight);
			}
		}
		return size;
	}
protected:
	Node* _root;
};

Test.cpp

#include <iostream>
#include "Tree.h"
using namespace std;

void Test()
{
        int arr1[11] = { 1, 2, 3, ‘#‘, ‘#‘, 4, ‘#‘, ‘#‘, 5, ‘#‘, ‘#‘};
	CompleteBinaryTree<int> cbt1(arr1,sizeof(arr1)/sizeof(arr1[0]));
 	std::cout << cbt1.Count() << std::endl;

	int arr2[21] = { 1, 2, 3, 4, ‘#‘, ‘#‘, 5, ‘#‘, ‘#‘, 6, 7, ‘#‘, ‘#‘ ,‘#‘, 8, 9, ‘#‘, ‘#‘, 10, ‘#‘, ‘#‘};
	CompleteBinaryTree<int> cbt2(arr,sizeof(arr2)/sizeof(arr2[0]));
 	std::cout << cbt2.Count() << std::endl;
}

int main()
{
	Test();

	system("pause");
	return 0;
}

测试结果:

输出 5

10

《完》

时间: 2024-10-15 10:54:13

求一棵完全二叉树的节点数(不通过遍历)的相关文章

二叉树——求一棵完全二叉树节点的个数

已知一棵完全二叉树, 求其节点的个数要求: 时间复杂度低于O(N), N为这棵树的节点个数 结论:满二叉树:高度为L,结点个数  2^L  - 1个 先遍历左边界,求出完全二叉树的高度h 然后遍历树的右子树的左边界,看它到没到最后一层, 如果到了最后一层,那么证明它的左子树是满的,高度是h-1        左子树的结点数2^(h-1) - 1  + 当前节点 + 递归求解 右子树的结点的个数 如果没到最后一层,那么证明它的右子树是满的,高度是h-2        右子树的结点数2^(h-2)

LeetCode222 Count CompleteTree Nodes(计算完全二叉树的节点数) Java 题解

题目: Given a complete binary tree, count the number of nodes. Definition of a complete binary tree from Wikipedia: In a complete binary tree every level, except possibly the last, is completely filled, and all nodes in the last level are as far left a

(hdu step 5.1.5)Dragon Balls(求并查集的根节点、节点数和个结点的移动次数)

题目: Dragon Balls Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 562 Accepted Submission(s): 239   Problem Description Five hundred years later, the number of dragon balls will increase unexpected

二叉树(8)----求二叉树第K层的节点数和二叉树第K层的叶子节点数,递归方式

1.二叉树定义 typedef struct BTreeNodeElement_t_ { void *data; } BTreeNodeElement_t; typedef struct BTreeNode_t_ { BTreeNodeElement_t *m_pElemt; struct BTreeNode_t_ *m_pLeft; struct BTreeNode_t_ *m_pRight; } BTreeNode_t; 2.求二叉树第K层的节点数 (1)递归方式 给定根节点pRoot: 如

求解完全二叉树的节点总数 Python实现

1.利用一般递归即可求得 1 def getNodeNums(head): 2 if not head: 3 return 0 4 lnums = getNodeNums(head.left) 5 rnums = getNodeNums(head.right) 6 return lnums + rnums + 1 2.利用完全二叉树的特性递归(时间复杂度O(logn*logn)) 1 # 利用完全二叉树特性,使用递归 时间复杂度:O(logn*logn) 2 # 满二叉树节点总个数为2**n-1

Leetcode 222.完全二叉树的节点个数

完全二叉树的节点个数 给出一个完全二叉树,求出该树的节点个数. 说明: 完全二叉树的定义如下:在完全二叉树中,除了最底层节点可能没填满外,其余每层节点数都达到最大值,并且最下面一层的节点都集中在该层最左边的若干位置.若最底层为第 h 层,则该层包含 1~ 2h 个节点. 示例: 输入: 1 / \ 2 3 / \ / 4 5 6 输出: 6 1 public class Solution { 2 3 // 获取左子树的高度(其实是最左侧分支) 4 public int getLeftHeight

[Swift]LeetCode222. 完全二叉树的节点个数 | Count Complete Tree Nodes

Given a complete binary tree, count the number of nodes. Note: Definition of a complete binary tree from Wikipedia:In a complete binary tree every level, except possibly the last, is completely filled, and all nodes in the last level are as far left

LeetCode 222. 完全二叉树的节点个数(Count Complete Tree Nodes)

题目描述 给出一个完全二叉树,求出该树的节点个数. 说明: 完全二叉树的定义如下:在完全二叉树中,除了最底层节点可能没填满外,其余每层节点数都达到最大值,并且最下面一层的节点都集中在该层最左边的若干位置.若最底层为第 h 层,则该层包含 1~ 2h 个节点. 示例: 输入: 1 / 2 3 / \ / 4 5 6 输出: 6 解题思路 从根节点开始分别判断左右子树的高度: 若左子树高度等于右子树,说明左子树一定为满二叉树,可得左子树的总节点个数,然后递归求右子树的节点数: 若左子树高度大于右子树

poj 2401 划分树 求区间第k大的数

题目:http://poj.org/problem?id=2104 划分树待我好好理解下再写个教程吧,觉得网上的内容一般,,, 模板题: 贴代码: #include <iostream> #include <cstdio> #include <cstring> #include <algorithm> using namespace std; #define CLR(a) memset(a,0,sizeof(a)) const int MAXN = 1000