二叉树的习题

博客围绕二叉树展开,涵盖求结点个数、叶子结点、树高度、第K层结点个数等计算,还有查找特定值结点地址、前序遍历等操作。同时包含树的比较判断,如是否相同、镜像对称、为子树、平衡二叉树、完全二叉树等,以及用前序和中序还原二叉树、找最近公共祖先等内容。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

求树中结点个数

int Size2(Node *root) {
	if (root == NULL) { return 0; }
	else if (root->left == NULL && root->right == NULL) { return 1; }
	else {
		int left = Size2(root->left);
		int right = Size2(root->right);
		return left + right + 1;
	}
	 
}

求叶子结点

int LeafSize(Node *root) {
	if (root == NULL) { return 0; }
	else if (root->left == NULL && root->right == NULL) { return 1; }
	else {
		int left = LeafSize(root->left);
		int right = LeafSize(root->right);
		return left + right ;
	}
}

求二叉树高度

int Height(Node *root) {
	if (root == NULL) { return 0; }
	else if (root->left == NULL && root->right == NULL) { return 1; }
	else {
		if (root->left != NULL || root->right != NULL) {
			int left = Height(root->left);
			int right = Height(root->right);
			return left < right ? (right + 1) : (left + 1);
		}
	}
}

求二叉树第K层结点个数

int KLevelSize(Node *root, int k) {
	if (root == NULL) { return 0; }
	if (k == 1) { return 1; }
	int left = KLevelSize(root->left,k-1);
	int right = KLevelSize(root->right,k-1);
	return left + right;
}

查找含有value值的结点地址

Node* Find(Node* root,int v) {
	if (root == NULL) 
	{ return NULL; }
	if (root->value == v)
	{ return root; }
	Node *result = Find(root->left, v);
	if (result != NULL) 
	{ return result; }
	result = Find(root->right, v);
	if (result != NULL) 
	{ return result; }
	return NULL;
}

二叉树的前序遍历,返回一个给定值的数组

int *array;
int size;
void Preorder(Node *root) 
{
	if (root == NULL) {
		return;
	}
	//printf("%d", root->value);
	array[size++] = root->value;
	Preorder(root->left);
	Preorder(root->right);
}
int* preorderTraversal(Node *root,int* returnSize) {
	array = (int*)malloc(sizeof(int) * 100 * 10000);
	size = 0;
	Preorder(root);
	*returnSize = size;
	return array;
}

检查两个树是否相同

bool isSameTree(Node *root1, Node *root2) {
	if (root1 == NULL && root2 == NULL) { return true; }
	if (root1 == NULL || root2 == NULL) { return false; }
	return root1->value == root2->value
		&& isSameTree(root1->left, root2->left)
		&& isSameTree(root1->right, root2->right);
}

两棵树是否镜像对称

bool isMirror(Node *root1,Node *root2) {
	if (root1 == NULL && root2 == NULL) { return true; }
	if (root1 == NULL || root2 == NULL) { return false; }
	return root1->value == root2->value
		&& isSameTree(root1->left, root2->right)
		&& isSameTree(root1->right, root2->left);
}

一个树是否是另一个树的子树

bool Find1(Node *r, Node *t){
	if (r == NULL) { return false; }
	if (isSameTree(r, t) == true) { return true; }
	if (Find1(r->left, t) == true) { return true; }
	return Find1(r->right, t);
}
bool isSubtree(Node *s, Node *t)
 { return Find1(s, t); }

判断一个树是否为平衡二叉树(每个节点的左右子树的高度差的绝对值不超过1)

bool Balanced(Node *root) {
	if (root == NULL) { return true; }
	if (Balanced(root->left) == false) { return false; }
	if (Balanced(root->right) == false) { return false; }
	int left = Height(root->left);
	int right = Height(root->right);
	int d = left - right;
	if (d < -1 || d>1) { return false; }
	return true;
}

用前序+中序还原二叉树

Node* buildTree(char preorder[], char inorder[], int size) {
	if (size == 0) { return NULL; }
	char rootValue = preorder[0];
	int leftSize = find(inorder, size, rootValue);
	assert(leftSize != -1);

	Node *root = (Node*)malloc(sizeof(Node));
	root->value = rootValue;
	root->left = buildTree(preorder + 1, inorder, leftSize);
	root->right = buildTree(preorder + 1 + leftSize, inorder + leftSize + 1, size - 1 - leftSize);
	return root;
}

int find(char array[], int size, char v) {
	for (int i = 0; i < size; i++) {
		if (array[i] == v) { return i; }
	}
	return -1;
}

找二叉树的最近公共祖先

Node* lowestcommmonAncestor(Node *root, Node *p, Node *q) {
	if (root == p || root == q) { return root; }
	bool pInLeft = Find1(root->left, p);
	bool qInLeft = Find1(root->left, q);
	if (pInLeft&&qInLeft) { return lowestcommmonAncestor(root->left, p, q);}
	if (pInLeft==false&&qInLeft==false) { return lowestcommmonAncestor(root->right, p, q); }
	return root;
}

判断是否是完全二叉树

1.如果树不为空,层序遍历二叉树

2.如果遇到一个结点左右孩子都不为空,则pop该节点,将其左右孩子入队列

3.如果遇到一个结点,左孩子为空,右孩子不为空,则该树不一定完全二叉树

4.如果一个结点,左孩子不为空,右孩子为空;或者左右孩子都为空;则该节点之后的队列中的结点都为叶子结点,该树才为完全二叉树

bool isComplete(Node *root) {
	if (root == NULL) { return true; }
	std::queue<Node*> q; 
	q.push(root);
	while (true) {
		Node *front = q.front();
		q.pop();
		if (front == NULL) { break; }
		q.push(front->left);
		q.push(front->right);
	}
	//判断队列剩余元素是否全是NULL
	while (!q.empty()) {
		Node *front = q.front();
		q.pop();
		if (front != NULL) { return false; }
	}
	return true;
}

非递归前序遍历

void PreOrderNor(Node *root) {
	std::stack<Node*> s;
	Node *cur = root;
	while (cur != NULL || s.empty()) {
		while (cur != NULL) {
			printf("%d", cur->value);
			s.push();
			cur = cur->left;
		}
	Node *top = s.top();
	s.pop();
	cur = top->right;
}
}

 

(1)非递归定义 树(tree)是由n(n≥0)个结点组成的有限集合。n=0的树称为空树;n>0的树T: ① 有且仅有一个结点n0,它没有前驱结点,只有后继结点。n0称作树的根(root)结点。 ② 除结点外n0 , 其余的每一个结点都有且仅有一个直接前驱结点;有零个或多个直接后继结点。 (2)递归定义 一颗大树分成几个大的分枝,每个大分枝再分成几个小分枝,小分枝再分成更小的分枝,… ,每个分枝也都是一颗树,由此我们可以给出树的递归定义。 树(tree)是由n(n≥0)个结点组成的有限集合。n=0的树称为空树;n>0的树T: ① 有且仅有一个结点n0,它没有前驱结点,只有后继结点。n0称作树的根(root)结点。 ② 除根结点之外的其他结点分为m(m≥0)个互不相交的集合T0,T1,…,Tm-1,其中每个集合Ti(0≤i<m)本身又是一棵树,称为根的子树(subtree)。 2、掌握树的各种术语: (1) 父母、孩子与兄弟结点 (2) 度 (3) 结点层次、树的高度 (4) 边、路径 (5) 无序树、有序树 (6) 森林 3、二叉树的定义 二叉树(binary tree)是由n(n≥0)个结点组成的有限集合,此集合或者为空,或者由一个根结点加上两棵分别称为左、右子树的,互不相交的二叉树组成。 二叉树可以为空集,因此根可以有空的左子树或者右子树,亦或者左、右子树皆为空。 4、掌握二叉树的五个性质 5、二叉树的二叉链表存储。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值