【数据结构】 ——二叉树性质以及常用接口

一、二叉树的概念

在计算机科学中,二叉树是每个节点最多有两个子树的树结构。通常子树被称作“左子树”(left subtree)和“右子树”(right subtree),二叉树常被用于实现二叉查找树和二叉堆.(摘自百度百科)

1、什么是满二叉树?

除了最后一层无任何子节点外,每一层上的所有节点都有两个子节点二叉树。
在这里插入图片描述

2、什么是完全二叉树?

一棵二叉树中,只有最下面两层结点的度可以小于2,并且最下层的叶结点集中在靠左的若干位置上,这样的二叉树称为完全二叉树。
在这里插入图片描述

3、什么是二叉查找树?

二叉查找树又被称为二叉搜索树。设x为二叉查找树中的一个结点,x结点包含关键字key,结点x的key值计为key[x]。如果y是x的左子树中的一个结点,则key[y]<=key[x];如果y是x的右子树的一个结点,则key[y]>=key[x]
在这里插入图片描述

在二叉查找树中:

(1)若任意结点的左子树不空,则左子树上所有结点的值均小于它的根结点的值。

(2)任意结点的右子树不空,则右子树上所有结点的值均大于它的根结点的值。

(3)任意结点的左、右子树也分别为二叉查找树。

(4)没有键值相等的结点。

二、二叉树的性质

性质1:二叉树第i层上的结点数目最多为2i-1(i>=1)

性质2:深度为k的二叉树至多有2k-1个结点(k>=1)

性质3:包含n个结点的二叉树的高度至少为(log2n)+1

性质4:在任意一棵二叉树中,若终端结点的个数为n0,度为2的结点数为n2,则n0=n2+1

三、二叉树的常用接口实现

  • 结构体定义:
struct TreeNode
{
		int val;
	TreeNode *left;
	TreeNode* right;
	TreeNode(int x):val(x),left(NULL),right(NULL)
	{}
};
 - 以下是先序遍历递归与非递归接口
 - 中序遍历的递归与非递归接口
 - 后序遍历的递归与非递归接口
 - 层次遍历二叉树
 - 求二叉树的深度递归与非递归
 - 判断一棵树是否为平衡二叉树


//先序遍历
//递归版本
void PreTraversal(vector<int> &v, TreeNode* root)
{
	if (!root)
		return;
	v.push_back(root);
	PreTraversal(v, root->left);
	PreTraversal(v, root->right);
}
//非递归版本
void PreTraversal(vector<int> &v, TreeNode* root)
{
	stack<TreeNode*> s;
	s.push(root);
	while (!s.empty())
	{
		TreeNode *cur = s.top();
		s.pop();
		if (temp)
		{
			v.push_back(cur->val);
			s.push(root->right);
			s.push(root->left);
		}
	}
}

//中序遍历  //左根右
void InorderTraversal(vector<int> &v, TreeNode* root)
{
	if (!root) return;
	InorderTraversal(v, root->left);
	v.push(root->val);
	InorderTraversal(v, root->right);
}

//非递归遍历
void InorderTraversal(vector<int> &v, TreeNode* root)
{
	TreeNode* cur = root;
	stack<TreeNode*> s;
	while (root||!s.empty())
	{
		while (root)
		{
			s.push(root);
			root = root->left;
		}
		TreeNode* cur = s.top();
		s.pop();
		v.push_back(cur->val);
		root = cur->right;
	}
}
//后序遍历
void PostorderTraversal(vector<int> &v, TreeNode* root)
{
	if (!root) return;
	PostorderTraversal(v, root->left);
	PostorderTraversal(v, root->right);
	v.push(root->val);
}
//非递归版本
void postOrderTraversal(vector<int> &store, TreeNode *root) {
	stack<TreeNode *> S;
	S.push(root);
	while (!S.empty()) {
		TreeNode *curr_node = S.top();
		S.pop();
		if (curr_node) {
			store.push_back(curr_node->val);
			S.push(curr_node->left);    //右孩子优先,所以左孩子先入栈
			S.push(curr_node->right);
		}
	}
	std::reverse(store.begin(), store.end());   //逆序列即为所求
	return;
}

//层次遍历
void LevelOrderTraversal(vector<int> &v, TreeNode *root)
{
	queue<TreeNode*> q;
	q.push(root);
	while (!q.empty())
	{
		TreeNode* ret = q->front();
		q.pop();
		if (ret)
		{
			v.push_back(ret->val);
			q.push(ret->_left);
			q.push(ret->right);
		}
	}
}

//二叉树的深度
int TreeDeepTh(TreeNode* root)
{
	//递归法
	return root ? 1 + max(TreeDeepth(root->left), TreeDeepth(root->right)):0;
}
//迭代法  用到层次遍历,层次就是我们的深度
int TreeDeepTh(TreeNode* root)
{
	if (!root)
	{
		return 0;
	}
	int depth = 0;
	queue<TreeNode*> q;
	q.push(root);
	while (!q.empty())
	{
		int length = q.size();
		++depth;
		while (length--)
		{
			TreeNode* ret = q->front();
			q.pop();
			if (ret)
			{
				v.push_back(ret->val);
				q.push(ret->_left);
				q.push(ret->right);
				length++;
			}
		}
		
	}
	return length;
}

//判断一棵树是否为平衡二叉树:平衡二叉树是指:它是一颗空树
//或者左右子树的高度差不超过1,并且左右子树都是一颗平衡二叉树
bool Isbalanced(TreeNode * root,int &Deepth)
{
	if (!root)
	{
		Deepth = 0;
		return true;
	}
	int left_depth, right_depth;
	if (Isbalanced(root->left, left_depth) && Isbalanced(root->right, right_depth))
	{
		int diff = left_depth - right_depth;
		if (diff <= 1 && diff >= -1)
		{
			Deepth = 1 + ((left_depth > right_depth) ? left_depth : right_depth);
			return true;
		}
	}
	return false;

}
bool IsBlancedTree(TreeNode* root)
{
	int Deepth = 0;
	return Isbalanced(root, Deepth);
}

发布了33 篇原创文章 · 获赞 13 · 访问量 1031

猜你喜欢

转载自blog.csdn.net/Vicky_Cr/article/details/105201618