二叉树(真题)

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的左孩子再次入栈 
			} 

		}
	}
}

(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、二叉树的二叉链表存储。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值