数据结构——树及二叉树知识整理

1.存在一棵总共有2016个结点的二叉树,其中有16个结点只有一个孩子(F)

解析:假设没有孩子的结点(叶结点)个数为n₀,只有一个孩子的结点(度为1的结点)个数为n₁,有两个孩子的结点(度为2的结点)个数为n₂。则n₀+n₁+n₂=2016
        则n₀+n₁+n₂=2016,n₁+2n₂+1=2016

        且依据非空二叉树的叶子结点树等于双支结点数+1,n₀=n₂+1
        ⇨n₂+1+16+n₂=2016
        ⇨2n₂=1999,n₂除不尽

2.二叉树就是度为 2 的树(F)

解析:度为2的树至少有一个结点的度为2,但二叉树没有这种要求;度为2 的树不区分左、右子树,而二叉树严格区分左、右子树;度为2的树至少要3个结点,而二叉树的结点可以为0

3.二叉树(有序树)不是树(无序树)的特殊情况(即度为 2 的树)(T)

解析:树是树,二叉树是二叉树,树并没有包含二叉树 ,但是他们都属于树形结构

4.设深度为d(只有一个根结点时,d为1)的二叉树只有度为0和2的结点,则此类二叉树的结点数至少为2d-1(T)

解析:题目中只提到二叉树只有度为0和2的结点,但没有说明叶子结点都在最后一层,所以题中的二叉树不一定为满二叉树,树中每一层只有左子树有孩子结点,则二叉树的结点树至少有2d-1个,除了根结点那层只有一个,其余层都为2个结点,如图所示,

5.一棵树中位于同一层上的结点称为兄弟结点(F)

解析:在同一层上的结点不一定为兄弟结点,兄弟结点要具有同一个双亲结点

6.树形结构:一对多

   图形结构:多对多

   线性结构:一对一

7.树最适合于用来表示元素之间具有分支层次关系的数据,树是一种抽象数据类型或是实现这种抽象数据类型的数据结构,用来模拟具有树状结构性质的数据集合。它是由n(n>0)个有限节点组成一个具有层次关系的集合

8.树具有以下几种特点

  • 每个节点有零个或多个子节点
  • 没有父节点的节点称为根节点
  • 每一个非根节点有且只有一个父节点
  • 除了根节点外,每个子节点可以分为多个不相交的子树

9.如果一棵非空k(k≥2)叉树T中每个非叶子结点都有k个孩子,则称T为正则k叉树。若T的高度为h(单结点的树h=1),则T的结点数最多为:(k^h−1)/(k−1)

解析:第一层结点树为1,第二层为k,第三层为k^2,第n层为k^n-1,成等比数列,依据等比数列公式可得,高度为h的k叉树结点数最多为(k^h−1)/(k−1)

10.二叉树遍历相关习题

解析代码如下,

#include<stdio.h>
#include<malloc.h>
typedef struct TreeNode
{
    int val;        //数据元素
    struct TreeNode *left;        //指向左右孩子的指针
    struct TreeNode *right;
}TreeNode;
//构建二叉树
TreeNode* buildTree(int min[],int post[],int n)
{
    if(!n)
        return NULL;
    //创建一个新结点,值为后序遍历的最后一个元素
    TreeNode *T=(TreeNode *)malloc(sizeof(struct TreeNode));
    T->val=post[n-1];
    T->left=T->right=NULL;
    //在中序遍历中找到与后序遍历最后一个元素相同的值
    int index;
    for(index=0;index<n;index++)
    {
        if(min[index]==post[n-1])        //确认根结点的位置
            break;
    }
    //递归构建左右子树
    T->left=buildTree(min,post,index);
    T->right=buildTree(min+index+1,post+index,n-index-1);    //右子树的数量为n-index-1,为总数减去根结点和左子树的值
    return T;
}
//层次遍历二叉树
void LevelOrder(TreeNode *T)
{
    if(T)
    {
        //使用数组模拟队列
        TreeNode *queue[100];
        int left=0,right=0;
        queue[right++]=T;        //根结点入队
        while(left<right)
        {
            TreeNode *bt=queue[left++];
            if(bt==T)
                printf("%d",bt->val);
            else
                printf(" %d",bt->val);
            //将左右子结点入队
            if(bt->left)
                queue[right++]=bt->left;
            if(bt->right)
                queue[right++]=bt->right;
        }
    }
}
int main()
{
    int num;
    scanf("%d",&num);
    int post[100];
    int min[100];
    //输入后序遍历和中序遍历的结果
    for(int i=0;i<num;i++)
    {
        scanf("%d",&post[i]);
    }
    for(int i=0;i<num;i++)
    {
        scanf("%d",&min[i]);
    }
    TreeNode TN=*buildTree(min,post,num);
    LevelOrder(&TN);
    return 0;
}

注:后序遍历为左子树->右子树->根结点

       中序遍历为左子树->根结点->右子树

        前序遍历为根结点->左子树->右子树

11.二叉树的相关算法

  • 结构体定义
typedef char ElemType; 
typedef struct node
{
	ElemType data;	//数据元素 
	struct node *lchild;	//左孩子指针 
	struct node *rchild; 	//右孩子指针 
 }BTNode;
  • 创建二叉树
void CreateBTree(BTNode *&b,char *str)
{
	BTNode *St[MaxSize],*p;
	int top=-1,k,j=0;	//top为栈指针,k用于判断左右子树  
	b=NULL;		//初始化空树 
	char ch;
	ch=str[j];
	while(ch!='\0')		//当字符串为'\0'时停止循环 
	{
		switch(ch)		//判断ch 
		{
			case '(':	//开始处理左子树 
				top++;
				St[top]=p;		//将左括号前的字符入栈 
				k=1;
				break;
			case ')':			//子树处理完毕 
				top--;
				break;
			case ',':		//开始处理右子树 
				k=2;
				break;
			default:
				p=(BTNode *)malloc(sizeof(BTNode));		//为字符分配空间 
				p->data=ch;
				p->lchild=p->rchild=NULL;		//初始化左右子树为空 
				if(b==NULL) 
				{
					b=p;	//若b为空,则p为根结点 
				}else{
					switch(k)		//判断k值,确定字符为左子树还是右子树 
					{
						case 1:
							St[top]->lchild=p;		//入栈左子树 
							break;
						case 2:
							St[top]->rchild=p;
							break;
					}
				}
		}
		j++;		//j自增,字符向下移动一位 
		ch=str[j];
	}
 } 
  • 销毁二叉树
void DestroyBTree(BTNode *&b)
{
	if(b!=NULL)
	{
		DestroyBTree(b->lchild);		//递归销毁 
		DestroyBTree(b->rchild);
		free(b);
	}
}
  • 输出二叉树
void DispBTree(BTNode *b)
{
	if(b!=NULL)
	{
		printf("%c",b->data);		//输出根结点 
		if(b->lchild!=NULL||b->rchild!=NULL)		//判断左右子树是否为空 
		{
			printf("(");		//左子树不为空,先输出左括号,再输出左子树的字符 
			DispBTree(b->lchild);
			if(b->rchild!=NULL)		//右子树不为空,先输出,,再输出右子树的字符,最后输出右括号 
			{
				printf(",");
				DispBTree(b->rchild);
				printf(")");
			}
		}
	}
 } 
  • 查找二叉树的结点
BTNode *FindNode(BTNode *b,ElemType x)
{
	BTNode *p;
	if(b==NULL)		//当b为空时,b内无结点 
	{
		return NULL;
	}
	else if(b->data==x)		//判断根结点是否为查找对象 
	{
		return b;
	}
	else
	{
		p=FindNode(b->lchild,x);		//递归查找 
		if(p!=NULL)
		{
			return p;
		}else{
			return (FindNode(b->rchild,x));
		}
	}
 } 
  • 查找孩子结点
BTNode *LchildNode(BTNode *p)
{
	return p->lchild;		//查找左孩子结点 
 } 
BTNode *RchildNode(BTNode *p)
{
	return p->rchild;		//查找右孩子结点 
}
  • 求二叉树的高度
int BTHeight(BTNode *b)
{
	int lchild,rchild;
	if(b==NULL)		//若树为空,则高度为0 
	{
		return 0; 
	}
	else
	{
		lchild=BTHeight(b->lchild);		//递归求出左右子树的高度 
		rchild=BTHeight(b->rchild);
		return (lchild>rchild)?(lchild+1):(rchild+1);		//比较左右子树的高度,取较大的值 
	}
}

  • 24
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值