二叉树(真题)

1.用非递归遍历求二叉树结点个数【计学2020】

算法思想:用先序非递归遍历

当前指针不为空或栈不为空进行循环;

当前指针不为空访问当前结点,当前节点入栈,进入左子树

当前指针为空,栈顶元素出栈(回溯),进入右子树

#include<malloc.h>
#define MaxSize 100
typedef struct node
{
	int data;
	struct node* left;
	struct node* right;
}BTNode;

BTNode* BuyNode(int a)//a是要创建的值
{
	BTNode* newnode = (BTNode*)malloc(sizeof(BTNode));//定义临时变量扩容
	if (newnode == NULL)
	{
		printf("malloc fail");//扩容失败
		return NULL;
	}
	newnode->data = a;
	newnode->left = NULL;
	newnode->right = NULL;
	return newnode;
}


BTNode* BinaryTreeCreate()//二叉树一般需要手动扩建
{
	BTNode* n1 = BuyNode(5);
	BTNode* n2 = BuyNode(4);
	BTNode* n3 = BuyNode(6);
	BTNode* n4 = BuyNode(2);
	BTNode* n5 = BuyNode(1);

	n1->left = n2;
	n1->right = n3;
	n2->left = n4;
	n2->right = n5;

	return n1;
}

int preOrder(BTNode* T)
{
	BTNode* stack[MaxSize];
	int count = 0;//节点个数
	int top = -1;//栈顶指针
	BTNode* cur = T;
	while(cur != NULL || top != -1)
	{
		if(cur != NULL)
		{
			count++;//相当于根 ,计数器 
			stack[++top] = cur;//入栈 
			cur = cur->left;//遍历左子树 
		}
		else
		{
			cur = stack[top];
			top--;//栈顶元素出栈 
			cur = cur->right;//遍历右子树 
		}
	}
	return count;
}
// 二叉树前序遍历 
void BinaryTreePrevOrder(BTNode* root) 
{
	if (root == NULL)
	{

		return;
	}
	printf("%d ", root->data);//打印节点
	BinaryTreePrevOrder(root->left);//访问左节点
	BinaryTreePrevOrder(root->right);//访问右节点

}
int main()
{

	BTNode* T = BinaryTreeCreate();//创建二叉树

	printf("%d",preOrder(T));
	BinaryTreePrevOrder(T);
	
	return 0;
}

2.判断二叉树中是否有平衡结点

算法思想:

 递归三部曲

  1、找递归终止条件
  2、找返回值:应该给上一级返回什么信息?
  3、本级递归应该做什么:在这一级递归中,应该完成什任务?

        本级递归需要算出左子树之和与右子树之和并比较

int postOrder(BTNode* root,bool* have)
{
	if(root == NULL)//
		return 0;
	if(root->left == NULL && root->right == NULL)//递归终止条件 
	{
		return root->data;
	}
	int leftSum =  postOrder(root->left, have);
	int rightSum =  postOrder(root->right, have);
	if(leftSum == rightSum)
	{
		*have = true;
	}
	return leftSum + rightSum + root->data;//返回给上一层的信息:算出左右子树以及当前节点之和
}
int isBalance(BTNode* root)
{
	bool have = false;
	postOrder(root,&have);
	return have;
}

3.找二叉树中data域为x的所有祖先结点【2021计专】

算法思想:用非递归后序遍历,因为遍历到某结点时,栈中一定存储着当前元素的所有祖先节点

后序非递归遍历算法思想:

void searchParent(BTNode* T,int x)
{
	BTNode* stack[MaxSize];

	int top = -1;//栈顶指针
	BTNode* cur = T;
	BTNode* r = NULL;//辅助指针r,保存cur最近访问过的结点的地址
	while(cur != NULL || top != -1)
	{
		if(cur != NULL)//一路将所有左孩子入栈 
		{
			if(cur->data == x)
			{
				for(int i = 0; i <= top; i++)//此时栈中的元素一定是x的所有祖先 
				{
					printf("%d ",stack[i]->data);
				}
				return; 
			}

			stack[++top] = cur;//入栈 
			cur = cur->left;//遍历左子树 
		}
		else//没有左孩子了 
		{
			cur = stack[top];
			if(cur->right != NULL && r != cur->right)//右子树非空且未被访问 
			{
				cur = cur->right;//进入右子树 
			}
			else//是从右子树返回的 
			{
				cur = stack[top--];
				r = cur;//标记上个访问节点 
				cur = NULL;//重置访问指针,不重置就会把cur的左孩子再次入栈 
			} 

		}
	}
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值