码迷,mamicode.com
首页 > 其他好文 > 详细

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

时间:2016-08-05 01:07:15      阅读:108      评论:0      收藏:0      [点我收藏+]

标签:求一棵完全二叉树的节点数

分析:

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

步骤

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



《完》

本文出自 “零蛋蛋” 博客,谢绝转载!

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

标签:求一棵完全二叉树的节点数

原文地址:http://lingdandan.blog.51cto.com/10697032/1834550

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!