2021-02-28

最大堆顺序存储结构

已知二叉树深度K,求最大节点总数Sk
二叉树第i层上最多含有节点数为2i个,则深度为k(一共有k层,即第0 ~ k-1层)的二叉树最多含有节点数为20+21+22+ ······ + 2k-1个。观察可知,这是一个首项为1,公比为2的等差数列,由等比数列求和公式Sn = a1(1-qn) / 1-q = 1*(1-2^k) / 1-2 = 2k - 1,即节点总数为2k - 1个。
已知二叉树的节点总数N,求其深度k
二叉树的节点总数一定在k-1层节点最大节点数和k层节点最大节点总数之间,即2k-1-1 < N <= 2k-1。两边取对数解得㏒₂(N+1) <= k < ㏒₂(N+1)+1,k 取这两数之间得整数即可。
求指定节点的孩子节点编号和双亲节点编号
假设有编号为i的节点Ni(0 <= i < n),那么:1.若i=0,则Ni为根节点,无双亲;否则,Ni的双亲节点编号为[(i-1)/2]。2.Ni的左子节点编号为2i+1,右子节点编号为2i+2。

顺序存储结构二叉树节点是否存储了数据的判断方法
为了判断二叉树中某个节点处的数据是否为有效值,将需要存储的数据封装成节点结构体类型,该节点类型中有一个布尔变量state用来标记该节点是否为有效节点(即存储了数据),若某节点的state成员变量值为true,表明该节点中存放了数据,否则为空节点。

头文件:

#pragma once

#include<cmath>  //调用对数函数求二叉树深度
#include<iostream>

template<typename T>
struct Node{
	T data = T();
	//state为true表示该节点存放了数据,否则为空节点。
	bool state = false;
};

template<typename T>
class SqBTree {
public:
	typedef unsigned size_type;

	~SqBTree();
	SqBTree(size_type size);
	/************************************************************* 
	*  插入与删除操作并没有修改SqBTree对象的成员变量,修改的是   *
	*  SqBTree对象的arr成员所指向的堆区内存。                    *
	**************************************************************/

	//向指定编号处插入节点。
	bool insert(size_type pos, const Node<T>& node)const;
	//删除指定编号处的节点。
	bool erase(size_type pos)const;
	//判断指定编号处的节点是否存储了数据。
	bool is_Full(size_type pos)const;
	//获取指定节点的双亲节点地址。
	Node<T>* getParent(size_type pos)const;
	//获取指定节点的左子节点地址。
	Node<T>* getLeft(size_type pos)const;
	//获取指定节点的右子节点地址。
	Node<T>* getRight(size_type pos)const;
	//按编号顺序显示二叉树中的元素。
	void display()const;

private:
	Node<T>* arr = nullptr;
	size_type size = 0;
};

CPP文件:

#include"SqBTree.h"

template<typename T>
SqBTree<T>::~SqBTree()
{
	if (arr) delete[] arr;
}

template<typename T>
SqBTree<T>::SqBTree(size_type size):size(size)
{
	arr = new Node<T>[size];
}

template<typename T>
bool SqBTree<T>::insert(size_type pos, const Node<T>& node) const
{
	if (pos >= size) return false;
	arr[pos] = node;
	//指定编号处被插入了数据,则该处的节点状态置为true。
	arr[pos].state = true;
	return true;
}

template<typename T>
bool SqBTree<T>::erase(size_type pos) const
{
	if (size == 0 || pos >= size) return false;
	//将节点的数据域置为默认值。
	arr[pos].data = T();
	//将该节点的状态标志置0,表示该节点未存放数据。
	arr[pos].state = false;
	return true;
}

template<typename T>
bool SqBTree<T>::is_Full(size_type pos) const
{
	if (size == 0 || pos >= size) return false;
	return arr[pos].state;
}

template<typename T>
Node<T>* SqBTree<T>::getParent(size_type pos) const
{
	//根节点无双亲节点。
	if (pos == 0 || size <= 1 || pos >= size) return nullptr;
	return &arr[(pos - 1) / 2];
}

template<typename T>
Node<T>* SqBTree<T>::getLeft(size_type pos) const
{
	//计算最后一个节点的双亲节点编号。
	size_type num = static_cast<size_type>((size - 1 - 1) / 2);
	//指定节点编号pos有效性检查。若只有一个根节点,则没有左子节点。
	if (pos > num || size <= 1) return nullptr;
	return &arr[2 * pos + 1];
}

template<typename T>
Node<T>* SqBTree<T>::getRight(size_type pos) const
{
	//计算最后一个节点的双亲节点编号。
	size_type num = static_cast<size_type>((size - 1 - 1) / 2);
	//指定节点编号pos有效性检查。若只有两个节点,则没有右子节点。
	if (pos > num || size <= 2) return nullptr;
	return &arr[2 * pos + 2];
}

template<typename T>
void SqBTree<T>::display() const
{
	for (int i = 0; i != size; ++i) {
		std::cout << arr[i].data << " ";
	}
	std::cout << std::endl;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

weixin_48343353

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值