树形结构总结

1.树相关

1.1树及相关概念

树是由n个节点组成的有限集合,若n=0,则为空树,每个非空树都有一个根节点。
每个节点可以有多个子节点,没有子节点的节点称为叶子节点。

深度:根节点到任一节点的路径长,根节点的深度为1.

高度:任一节点到叶子节点的最长路径长,所以叶子节点的高度为0.
一棵树的高度等于根节点的高度。

1.2树的表示方法

普通树:
普通树的节点可以有多个子节点
在这里插入图片描述
树有多种表示方法:
双亲表示法
孩子表示法
孩子兄弟表示法

树的三种表示法

1.3树的应用场景

1、创建目录
目录有二级目录,二级目录有三级目录,整个结构就像树一样

2、思维导图
3、huffman编码
4、linux虚拟内存管理
5、B+、B-树(索引)
6、C++STL中的map、mutilmap、set、mutilset

2.二叉树

2.1二叉树的性质

二叉树的节点最多有两个左右子节点(度最多为2),例如:
在这里插入图片描述

性质:
1、在二叉树第i层(i>=1)最多有 2 i − 1 2^{i-1} 2i1个节点

2、深度为k(k>=0)的二叉树最少有k个节点,最多有 2 k − 1 2^k-1 2k1个节点

3、对任意一颗非空二叉树,如果其叶子节点数为n1,则其度数为2的非叶子节点数为n2,且n1 = n2 +1

4、具有n个节点的完全二叉树的最小深度为 log ⁡ 2 ( n + 1 ) \log_{2}{(n+1)} log2(n+1)

2.2满二叉树

如果二叉树的高度为k,其有 2 k − 1 2^k-1 2k1个节点,则为满二叉树,简单来说就是每个非叶子节点都有两个子节点

在这里插入图片描述

2.3完全二叉树

如果二叉树的高度为k,除第k层外,1~k-1层的节点都达到最大(为一颗满二叉树),且第k层的节点编号都与高度为k的满二叉树编号相对应,则为完全二叉树。例如:
在这里插入图片描述

2.4堆

具有一定特性的完全二叉树,一般用数组的形式来表示

堆分为大顶堆和小顶堆:

大顶堆:
所有非叶子节点都大于它的左右子节点

公式表示:vec[i] >= vec[2i+1] && vec[i] >= vec[2i+2]

在这里插入图片描述

小顶堆:
所有非叶子节点都小于它的左右子节点

公式表示:vec[i] <= vec[2i+1] && vec[i] <= vec[2i+2]
在这里插入图片描述

可以看看答主写的堆排序:
各种排序总结

2.5二叉树的基本操作

2.5.1实现

二叉树节点结构

template<typename T>
class BinaryTreeNode
{
public:
    T val;
	BinaryTreeNode<T>* left = nullptr;
	BinaryTreeNode<T>* right = nullptr;

	BinaryTreeNode(T data) :val(data){};//构造函数

};

二叉树结构

template<typename T>
class BinaryTree
{
public:

	BinaryTree()
	{
	}
	
	void Add(T data);
	
	void DestoryBinaryTree(BinaryTreeNode<T> * node);
	
	BinaryTreeNode<T>* getRoot()
	{
		return root;
	}
	~BinaryTree()
	{
		DestoryBinaryTree(root);
	}

private:
	BinaryTreeNode<T> * root = nullptr;
};

增加元素函数

template<typename T>
void BinaryTree<T>::Add(T data)
{
	BinaryTreeNode<T> * node = new BinaryTreeNode<T>(data);
	queue<BinaryTreeNode<T>*> que;
	que.push(root);
	if (!this->root)
	{
		root = node;
		return;
	}
	while (!que.empty())
	{
		BinaryTreeNode<T> * temp = que.front();
		que.pop();
		if (!temp->left)
		{
			temp->left = node;
			return;
		}
		else
		{
			que.push(temp->left);
		}
		if (!temp->right)
		{
			temp->right = node;
			return;
		}
		else
		{
			que.push(temp->right);
		}
	}
}

删除元素

template<typename T>
void BinaryTree<T>::DestoryBinaryTree(BinaryTreeNode<T> * node)
	{
		if (node)	//如果有节点
		{
			if (node->left)	//如果存在左孩子
			{
				DestoryBinaryTree(node->left);	//销毁二叉树的左子树
			}
			if (node->right)
			{
				DestoryBinaryTree(node->right);	//销毁二叉树的右子树
			}
		}
		delete node;	//销毁节点
		node = nullptr;
	}

2.5.2遍历

2.5.2.1层序遍历
void LevelOrder(BinaryTreeNode<T> * node)
	{
		if (!node)
		{
			return;
		}
		queue<BinaryTreeNode<T> *> que;
		que.push(node);

		while (!que.empty())
		{
			BinaryTreeNode<T> * temp = que.front();

			que.pop();
			cout << temp->val << " ";
			if (temp->left)
			{
				que.push(temp->left);
			}
			if (temp->right)
			{
				que.push(temp->right);
			}
		}
	}
2.5.2.2前序遍历

递归

void PreOrder(const BinaryTreeNode<T> * node )
	{
		if (!node)
		{
			return;
		}
		cout << node->val << " ";
		PreOrder(node->left);
		PreOrder(node->right);
	}

非递归

void WPreOrder(BinaryTreeNode<T> * node)
	{
		if (!node)
		{
			return;
		}
		stack<BinaryTreeNode<T> *> stk;
		BinaryTreeNode<T> * temp = node;
		while (!stk.empty() || temp)
		{
			if (temp)
			{
				stk.push(temp);
				cout << temp->val << " ";
				temp = temp->left;
			}
			else
			{
				temp = stk.top();
				stk.pop();
				temp = temp->right;
			}
		}
	}
2.5.2.3中序遍历

递归

void InOrder(const BinaryTreeNode<T> * node)
	{
		if (!node)
		{
			return;
		}
		InOrder(node->left);
		cout << node->val << " ";
		InOrder(node->right);
	}

非递归

void WInOrder(BinaryTreeNode<T> * node)
	{
		if (!node)
		{
			return;
		}
		stack<BinaryTreeNode<T> *> stk;
		BinaryTreeNode<T> * temp = node;
		while (!stk.empty() || temp)
		{
			if (temp)
			{
				stk.push(temp);
				temp = temp->left;
			}
			else
			{
				temp = stk.top();
				stk.pop();
				cout << temp->val << " ";
				temp = temp->right;
			}
		}
	}
2.5.2.4后序遍历

递归

void PostOrder(const BinaryTreeNode<T> * node)
	{
		if (!node)
		{
			return;
		}
		PostOrder(node->left);
		PostOrder(node->right);	
		cout << node->val << " ";
	}

非递归`

void WPostOrder(BinaryTreeNode<T> * node)
	{
		
		stack<BinaryTreeNode<T>*> stk1;
		stack<BinaryTreeNode<T>*> stk2;
		stk1.push(node);
		BinaryTreeNode<T>*  temp;

		while (!stk1.empty())
		{
			temp = stk1.top();
			stk1.pop();
			stk2.push(temp);

			if (temp->left)
			{
				stk1.push(temp->left);
			}
			if (temp->right)
			{
				stk1.push(temp->right);
			}
		}

		while (!stk2.empty())
		{
			temp = stk2.top();
			stk2.pop();
			cout << temp->val << " ";
		}

	}
  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值