代码改变世界

二叉树

  youxin  阅读(310)  评论(0编辑  收藏  举报

   二叉树性质如下:

 1 对任何一颗二叉树,如果其终端节点数为n0,度为2的节点数为n2,则n0=n2+1;

  2 具有n个结点的完全二叉树的深度为floor(logn)+1

  证明:假设深度为k :

     2^(k-1)-1<n<=2^k-1 或 2^(k-1)<=n<2^k

 于是k-1<=logn<k 因为k为整数 ,所以 k=int(logn)+1;

3 N个结点的完全二叉树各结点如果用顺序方式存储,则结点之间有如下关系:

 若I为结点编号则 如果I!=1,则其父结点的编号为I/2;
 如果2*I<=N,则其左儿子(即左子树的根结点)的编号为2*I;若2*I>N,则无左儿子;
 如果2*I+1<=N,则其右儿子的结点编号为2*I+1;若2*I+1>N,则无右儿子。
 
4 有n个节点的二叉链表中必定存在n+1个空链域。为什么?
空链域数=2n0+n1=2(n2+1)+n1=n1+2n2+1=n+1;
 
 
参考:
 

先序遍历的递归过程为

(1)访问根结点
(2)先序遍历根结点的左子树
(3)先序遍历根结点的右子树

而先序遍历的非递归过程为

先将根结点进栈,当栈不为空时,出栈并访问,然后依次将右左结点进栈(栈先进后出,所以先进栈右结点)

void NRPreOrder(Btnode *b)
{
	Btnode *p;    
	SqStack st;
	InitStack(st);
	if (b != NULL)      
	{
		Push(st, b);    //根结点入栈
		while (!StackEmpty(st))
		{
			Pop(st, p);                   //根结点出栈
			printf("%c",p->data);              //在此处用输出根接地那的值表示出栈
			if (p->right != NULL)         //当右子树非空
				Push(st, p->right);   //右孩子入栈
			if (p->left != NULL)          //当左子树非空
				Push(st, p->left);    //左孩子入栈
		}
		printf("\n");
	}
	DestroyStack(st);
}

还有一种前序遍历的非递归方式:

沿左子树深入时,入栈之前访问该结点
继续深入,为NULL时,则返回并弹出前面压入的节点
从该结点的右子树继续深入

编辑推荐:
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
阅读排行:
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通
点击右上角即可分享
微信分享提示